You are on page 1of 39

Multithreaded Programming

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

sleep interval When a thread completes


expires (returns from its run method),
interrupt it reaches the Dead state
(shown here as the final
state)
Thread Priorities

 Java thread priority


 Is an integer that specify the relative priority of
one thread to another.
 Priority in range 1-10
 Thread.MIN_PRIORITY = 0
 Thread.NORMAL_PRIORITY = 5
 Thread.MAX_PRIORITY = 10
 Each thread assigned time on the processor.
(called a quantum)
 Keeps highest priority threads running.
Ready threads

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

 Java’s multithreading systems is built upon


Thread class.
 To create a thread, you will either extends
thread class or implements the Runnable
interface.
 The thread class define several methods:
Methods Meaning
getName Obtain a thread’s name
getPriority Obtain a thread’s priority
isAlive Determine if a thread is still running
join Wait for a thread to terminate
run Entry point for the thread
sleep Suspend a thread for a period of time
start Start a thread by calling run method
The Main Thread
 When a java program starts up, one thread
begins running immediately that is called
“Main” thread.
 “Main” thread
 The thread from which other “child” thread will
be created.
 It must be the last thread to finish execution.
When the Main thread stops, your program
terminates.
// Controlling the main Thread.
class CurrentThreadDemo {
public static void main(String args[]) {
Thread t = Thread.currentThread();
Is a public static member
System.out.println("Current thread: " + t); of Thread class. This
methos returns a
// change the name of the thread reference to the thread in
t.setName("My Thread"); whice it is called.
System.out.println("After name change: " + t);

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

within that class.


 The construct of Thread class

 Thread (Runnable threadOb, String threadName)


 threadOb is an object of a class that implements the
Runnable.
 threadName specify the name of the thread.

 After calling start() the thread is started to


run.
 start() calls run() method to start the
execution of a thread.
class NT implements Runnable { class ThreadDemo {
Thread t;
public static void main(String args[])
NT() { {
// Create a new, second thread new NT(); // create a new thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
try {
} for(int i = 5; i > 0; i--) {
System.out.println("Main Thread:
// This is the entry point for the second thread.
public void run() { " + i);
try { Thread.sleep(1000);
for(int i = 1; i <= 5; i++) { }
System.out.println("Child Thread: " + i); } catch (InterruptedException e) {
Thread.sleep(500); System.out.println("Main thread
} interrupted.");
} catch (InterruptedException e) { }
System.out.println("Child interrupted."); System.out.println("Main thread
}
exiting.");
System.out.println("Exiting child thread.");
}
}
} }
 Output:
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 1
Child Thread: 2
Main Thread: 4
Child Thread: 3
Child Thread: 4
Main Thread: 3
Child Thread: 5
Exiting child thread.
Main Thread: 2
Main Thread: 1
Main thread exiting.
Creating Multiple Threads
// This is the entry point for thread.
class NewThread implements Runnable {
public void run() {
String name; // name of thread
try {
Thread t;
for(int i = 5; i > 0; i--) {
NewThread(String threadname) { System.out.println(name + ": " + i);
name = threadname; Thread.sleep(1000);
t = new Thread(this, name); }
System.out.println("New thread: " + t); } catch (InterruptedException e) {
t.start(); // Start the thread System.out.println(name +
} "Interrupted");
}
System.out.println(name + "
exiting.");
}
}
New thread: Thread[One,5,main]
class MultiThreadDemo { New thread: Thread[Two,5,main]
public static void main(String args[]) { New thread: Thread[Three,5,main]
new NewThread("One"); // start threads Two: 5
new NewThread("Two"); One: 5
new NewThread("Three"); Three: 5
Two: 4
try { One: 4
// wait for other threads to end Three: 4
Thread.sleep(10000); Two: 3
} catch (InterruptedException e) { Three: 3
System.out.println("Main thread One: 3
Interrupted"); Two: 2
} One: 2
Three: 2
System.out.println("Main thread Two: 1
exiting."); One: 1
} Three: 1
} Two exiting.
One exiting.
Three exiting.
Main thread exiting.
isAlive() and join() method
 How can one thread know when another
thread has ended?
 Two way to determine
 isAlive(): final boolean isAlive()
 Return true if the thread upon which it is called still
running, otherwise return false.
 join(): final void join() throws InterruptedException
 The methods waits until the thread on which it is
called terminates.
 The calling thread waiting until the specified 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
}

// This is the entry point for thread.


public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
}
class DemoJoin { try {
public static void main(String System.out.println("Waiting for
args[]) { threads to finish.");
NewThread ob1 = new ob1.t.join();
NewThread("One"); ob2.t.join();
ob3.t.join();
NewThread ob2 = new } catch (InterruptedException e) {
NewThread("Two"); System.out.println("Main thread
NewThread ob3 = new Interrupted");
NewThread("Three"); }

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;
} }

public void run() { public void start() {


while (running) { t.start();
click++; }
} }
}
class HiLoPri {
public static void main(String args[]) {
clicker hi = new clicker(Thread.NORM_PRIORITY + 2);
clicker lo = new clicker(Thread.NORM_PRIORITY - 2);

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");
}

System.out.println("Low-priority thread: " + lo.click);


System.out.println("High-priority thread: " + hi.click);
}
}
Output:
Low-priority thread: 14441978
High-priority thread: 159406749
Synchronization
 When two or more threads need to access to
a shared resource, it needs to ensure that the
shared resource is accessed by only one
thread at a time.
 Java uses the concept of monitor/semaphore
 Is an object that is used as a mutually exclusive
lock or mutex.
 Only one thread can own a monitor a given time.
 When a thread acquire a lock, all other threads
attempting to enter the locked monitor will be
suspended until the first thread exists the
monitor.
Using Synchronized methods
class SharedArea{
String str="";
synchronized void putSharedArea(String s)
{
str=str+"["+s;
try{
Thread.sleep(1000);
}catch(InterruptedException e)
{
System.out.println("Interrupted");
}
str=str+"] ";
}
void show()
{
System.out.println(str);
}
}
class Synch {
class Caller implements Runnable { public static void main(String args[]) {
String msg; SharedArea target=new SharedArea();
SharedArea targ; Caller ob1 = new Caller(target,"Hello");
Thread t; Caller ob2 = new
Caller(target,"Synchronized");
public Caller(SharedArea targ,String s) { Caller ob3 = new Caller(target,"World");
msg = s;
// wait for threads to end
this.targ=targ; try {
t = new Thread(this); ob1.t.join();
t.start(); ob2.t.join();
} ob3.t.join();
} catch(InterruptedException e) {
public void run() { System.out.println("Interrupted");
targ.putSharedArea(msg); }
} target.show();
}
}
}
Output:
[Hello[Synchronized[World] ] ]
 Output Should be:
 [Hello] [Synchronized] [World]
 To solve the problem you must somehow
restrict its access to only one thread at a time.
 Add synchronized keyword
 synchronized void putSharedArea(String s){
Using the synchronized
statement
 The general form of synchronized statement:
synchronized( object){
//statements to be synchronized
}
 Object is a reference to the object being

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

You might also like