Professional Documents
Culture Documents
Fundamentals
A multithreaded program contain two or
more parts that can run concurrently.
Each part of such a program is called thread.
There are two kinds of multitasking
Process-based multitasking
Thread-based multitasking
Process-based multitasking allows you to run
two or more program concurrently.
In thread-based multitasking a single
program can perform two or more task
simultaneously.
Life Cycle of a Thread
Born
start
Ready
thread dispatch
quantum expiration (assign a
yield processor)
timeout expires
I/O completes
notifyAll
interrupt
interrupt
acquire lock
notify
en
Running te
r
iss stasyn
re ue te chr
qu I m on
en i z
com
it es /O
p
t t ed
ee
wa
ple
sl
te
Waiting Sleeping Blocked
Thread.MAX_PRIORITY Priority 10 A B
Priority 9 C
Priority 8
Priority 7 D E F
Priority 6 G
Thread.NORM_PRIORITY Priority 5 H I
Priority 4
Priority 3
Priority 2 J K
Thread.MIN_PRIORITY Priority 1
The Thread class & Runnable
Interface
try {
for(int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}
}
}
Output:
Current thread: Thread[main,5,main]
After name change: Thread[My
Thread,5,main]
5
Thread Name Thread Priority
4
3 Thread Group
2
1
Creating Thread using
implementing Runnable
The easiest way to create a thread is to create a
class that implements the Runnable interface.
You can construct a thread on any object that
implements Runnable interface.
To implement Runnable
A class only need to implement a single method called
run(). Declaration: public void run().
run() is an entry point each thread.
Inside run()
Define the code that constitute the new thread.
Can call other methods, declare variables etc.
The thread will end when the run() returns.
After creating a class that implements Runnable
You will create an object of type Thread
joins it.
class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
System.out.println("Thread One is
System.out.println("Thread One
is alive: " + ob1.t.isAlive()); alive: " + ob1.t.isAlive());
System.out.println("Thread Two is
System.out.println("Thread Two alive: " + ob2.t.isAlive());
is alive: " + ob2.t.isAlive()); System.out.println("Thread Three
System.out.println("Thread Three is alive: " + ob3.t.isAlive());
is alive: "+ ob3.t.isAlive());
// wait for threads to finish System.out.println("Main thread
exiting.");
}
}
Output:
New thread: Thread[One,5,main] Two: 2
New thread: Thread[Two,5,main] One: 2
New thread: Thread[Three,5,main] Three: 1
Thread One is alive: true
One: 1
Thread Two is alive: true
Thread Three is alive: true Two: 1
Waiting for threads to finish. Three exiting.
One: 5 One exiting.
Three: 5 Two exiting.
Two: 5 Thread One is alive: false
One: 4
Three: 4
Thread Two is alive: false
Two: 4 Thread Three is alive: false
Three: 3 Main thread exiting.
Two: 3
One: 3
Three: 2
Thread Priorities
To set the thread’s priority, use the setPriority()
method, which is a member of Thread class
final void setPriority(int level)
level specifies the new priority setting for the calling threads.
To obtain current priority of a thread, use
getPriority() method
final int getPriority()
class clicker implements Runnable {
int click = 0;
Thread t;
private volatile boolean running = true;
public clicker(int p) {
t = new Thread(this); public void stop() {
t.setPriority(p); running = false;
} }
lo.start();
hi.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
lo.stop();
hi.stop();
// Wait for child threads to terminate.
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
synchronized.
void putSharedArea(String s)
{
str=str+"["+s;
try{
Thread.sleep(1000);
}catch(InterruptedException e)
{
System.out.println("Interrupted");
}
str=str+"] ";
}
No Synchronized keyword
public void run() {
synchronized(targ){
targ.putSharedArea(msg);
}
Inter-thread Communication
Polling
Implemented by a loop that is used to check
some condition repeatedly.
Once a condition is true, specific action is taken.
Wastes CPU time.
Example: printer queue
This is solve by inter-thread communication.
Three keywords are used:
wait()
notify()
notifyAll()
wait():
Tells the calling thread to give up the monitor
and go to sleep until some other thread that
enters the same monitor calls notify().
notify():
Wakes up the first thread that called wait() on
the same object.
notifyAll():
Wakes up all the threads that called wait() on the
same object. The height priority thread run first.
Incorrect Example
import java.util.Random;
class Q{
int head=0,tail=0;
int qu[]=new int[50000];
synchronized void push(int k){
qu[head]=k;
System.out.println("Producer: "+"["+head+"]: "+qu[head]);
head++;
}
synchronized void pop(){
System.out.println("Comsumer: "+"["+tail+"]: "+qu[tail]);
tail++;
}
}
class Producer implements Runnable{
Random r=new Random(); class Consumer implements
Q q; Runnable{
Producer(Q q){ Q q;
this.q=q; Consumer(Q q){
new this.q=q;
Thread(this,"Producer").start();
} new
Thread(this,"Consumer").start();
public void run() }
{
int k;
while(true){
public void run(){
k=r.nextInt(500); while(true)
q.push(k); {
} q.pop();
} }
}
}
}
Comsumer: [0]: 0
class PC{ Comsumer: [1]: 0
Comsumer: [2]: 0
public static void Comsumer: [3]: 0
main(String args[]) Comsumer: [4]: 0
Comsumer: [5]: 0
{ Comsumer: [6]: 0
Comsumer: [7]: 0
Q q=new Q(); Comsumer: [8]: 0
new Producer(q); Comsumer: [9]: 0
Comsumer: [10]: 0
new Consumer(q); Producer: [0]: 42
} Comsumer: [11]: 0
Producer: [1]: 400
} Comsumer: [12]: 0
Producer: [2]: 181
Comsumer: [13]: 0
Producer: [3]: 74
Corrected Example
import java.util.Random;
class Q{
int head=0,tail=0;
int qu[]=new int[50000];
boolean ispush=false;
synchronized void push(int k){
if(ispush)
{
try{
wait();
}catch(InterruptedException e){
System.out.println("Push Interrupted!");
}
}
ispush=true;
qu[head]=k;
System.out.println("Producer: "+"["+head+"]"+qu[head]);
head++;
notify();
}
synchronized void pop(){
if(!ispush)
{
try{
wait();
}catch(InterruptedException e){
System.out.println("Pop Interrupted!");
}
}
ispush=false;
System.out.println("Comsumer: "+"["+tail+"]"+qu[tail]);
tail++;
notify();
}
}
class Producer implements Runnable{
class Consumer implements Runnable{
Random r=new Random();
Q q; Q q;
Producer(Q q){ Consumer(Q q){
this.q=q; this.q=q;
new new
Thread(this,"Producer").start(); Thread(this,"Consumer").start();
} }// constructor End here
public void run(){
public void run()
while(true)
{
{
int k;
while(true) q.pop();
{ }
k=r.nextInt(500); }
q.push(k); }
}
}
}
class FixPC{
Producer: [0]2
public static void main(String args[]) Comsumer: [0]2
{ Producer: [1]295
Q q=new Q(); Comsumer: [1]295
new Producer(q); Producer: [2]404
Comsumer: [2]404
new Consumer(q); Producer: [3]319
} Comsumer: [3]319
} Producer: [4]105
Comsumer: [4]105
Producer: [5]197
Comsumer: [5]197
Producer: [6]209
Comsumer: [6]209
Producer: [7]169
Comsumer: [7]169