Multithreaded Programming
using Java Threads
Web/Internet Applications:
Serving Many Users Simultaneously
PC client
Internet
Server
Local Area Network
PD
A
2
Modern Applications need Threads (ex1):
Editing and Printing documents in background.
Printing Thread
Editing Thread
Multithreading is a conceptual programming paradigm
where a program (process) is divided into two or more
subprograms (processes), which can be implemented at
the same time in parallel.
A thread is a program that has a single flow of control
It has a beginning, a body, and an end, and executes
commands sequentially.
A unique property of java is its support for multi threading
Java enables us to use multiple flows of control in
developing programs
Each flow of control may be thought of as a separate tiny
program (or module) known as thread that runs in parallel
to others
A program that contains multiple flows of control is
known as Multithreaded program
A single threaded program
class ABC
{
.
public void main(..)
{
..
}
beginning
Single-threaded body
of execution
end
A Multithreaded Program
Main Thread
start
Thread A
start
Thread B
start
Thread C
Threads may switch or exchange data/results
8
Contd..
Java program with 4 threads, one main and three others
The main thread is actually the main method module,
which is designed to create and start the other three
threads, namely A,B and C
The threads A, B and C run concurrently and share the
resources concurrently
The ability of a language to support multithreads is
referred to as concurrency
Single and Multithreaded Processes
threads are light-weight processes within a process
Single-threaded Process
Multiple threaded Process
Threads of
Execution
Multiple instruction stream
Single instruction stream Common
Address Space
10
Benefits
It enables programmers to do multiple things at one
time
We can divide a long program (containing operations
that are conceptually concurrent) into threads and
execute them in parallel
11
Life cycle of a thread
Newborn state
Runnable state
Running state
Blocked state
Dead state
Life Cycle of Thread
Newborn
start
Active
Thread
stop
Runnable
Running
stop
Killed
Thread
yield
Suspend
resume
notify
Sleep
Dead
stop
wait
Idle Thread
(Not
Runnable)
Blocked
13
Newborn state
When we create a thread object, the thread is born and
is said to be in Newborn state
The thread is not yet scheduled for running
At this state, we can do only one of the following things
with it:
Schedule it for running using start() method
Kill it using stop() method
Newborn
start
Runnable state
stop
Dead State
Runnable state
Means that the thread is ready for execution and is
waiting for the availability of the processor
The process of assigning time to threads is known as
TIME-SLICING
YIELD
Running
Thread
Runnable threads
Relinquishing control using yield() method
Running State
This means that the processor has given its
time to the thread for its execution
A running thread may relinquish its control in
one of following situations:
Suspend
resume
Running
Runnable
suspended
Sleep(t)
After t
Running
Runnable
sleeping
wait
notify
Running
Runnable
waiting
Blocked state
A thread is said to be blocked when it is
prevented from entering into runnable
state and subsequently the running state.
Blocking a thread
A thread can be temporarily suspended or blocked from
entering into the runnable and subsequently running
state by using either of the methods:
sleep()
suspend()
wait()
// blocked for a specified time
// blocked until further orders
// blocked until certain condition occurs
These methods cause the thread to go into the blocked state (or not
runnable) state.
Sleep() : when specified time is elapsed
Suspend(): resume() method is invoked
Wait(): notify() method is invoked
Stopping a thread
Whenever we want to stop a thread from running
further, we may do by calling
aThread.stop();
This moves the thread to dead state.
The stop method may be used when the premature
death of a thread is desired
Creating threads
Threads are implemented in the form of objects
that contain a method called run()
A typical run() would appear as follows:
public void run()
{
..
.. (statements for implementing thread)
}
23
A new thread can be created in 2 ways:
By creating a thread class
By converting a class to a thread: Define a class
: Define a class that
extends thread class and override its run() method with the code
required by the thread
that implements Runnable interface. The Runnable interfaces
has only one method., run(), that is to defined in the method
with the code to be executed by the thread
24
Threading Mechanisms...
Create a class that extends the Thread class
Create a class that implements the Runnable interface
Thread
MyThread
(objects are threads)
[a]
Runnable
Thread
MyClass
(objects with run() body)
[b]
25
1st method: Extending Thread class
Create a class by extending Thread class and
override run() method:
class MyThread extends Thread
{
public void run()
{
// thread body of execution
}
}
Create a thread:
MyThread thr1 = new MyThread();
Start Execution of threads:
thr1.start();
//invokes run() method
Create and Execute:
new MyThread().start();
26
An
example
class MyThread extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println( this thread is running:i +i);
}
System.out.println(exit from A);
}
class ThreadEx1
{
public static void main (String [] args )
{
MyThread t = new MyThread();
t.start();
}
}
27
2nd method: Threads by
implementing Runnable interface
Create a class that implements the interface
Runnable and override run() method:
class MyThread implements Runnable
{
.....
public void run()
{
// thread body of execution
}
}
Creating Object:
MyThread myObject = new MyThread();
Creating Thread Object:
Thread thr1 = new Thread(myObject);
Start Execution:
thr1.start();
28
An example
class MyThread implements Runnable
{
public void run()
{
System.out.println(" this thread is running ... ");
}
}
class ThreadEx2
{
public static void main (String [] args )
{
Thread t = new Thread(new MyThread());
t.start();
}
}
29
A Program with Three Java Threads
Write a program that creates 3 threads
30
Three threads example
class A extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("\t From ThreadA: i= "+i);
}
System.out.println("Exit from A");
}
}
class B extends Thread
{
public void run()
{
for(int j=1;j<=5;j++)
{
System.out.println("\t From ThreadB: j= "+j);
}
System.out.println("Exit from B");
}
}
31
class C extends Thread
{
public void run()
{
for ( int k=1;k<=5;k++)
{
System.out.println ("\t From ThreadC: k= "+k);
}
System.out.println ("Exit from C");
}
}
class ThreadTest
{
public static void main (String args[])
{
new A().start();
new B().start();
new C().start();
}
}
32
Run 1
Javac ThreadTest.java
java ThreadTest
From ThreadA: i= 1
From ThreadA: i= 2
From ThreadA: i= 3
From ThreadA: i= 4
From ThreadA: i= 5
Exit from A
From ThreadC: k= 1
From ThreadC: k= 2
From ThreadC: k= 3
From ThreadC: k= 4
From ThreadC: k= 5
Exit from C
From ThreadB: j= 1
From ThreadB: j= 2
From ThreadB: j= 3
From ThreadB: j= 4
From ThreadB: j= 5
Exit from B
33
Run2
[raj@mundroo] threads [1:77] java ThreadTest
From ThreadA: i= 1
From ThreadA: i= 2
From ThreadA: i= 3
From ThreadA: i= 4
From ThreadA: i= 5
From ThreadC: k= 1
From ThreadC: k= 2
From ThreadC: k= 3
From ThreadC: k= 4
From ThreadC: k= 5
Exit from C
From ThreadB: j= 1
From ThreadB: j= 2
From ThreadB: j= 3
From ThreadB: j= 4
From ThreadB: j= 5
Exit from B
Exit from A
34
Example 2
class A extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
if(i==1) yield();
System.out.println("\t From Thread A: i= "+i);
}
System.out.println("Exit from A");
}}
class B extends Thread
{
public void run()
{
for(int j=1;j<=5;j++)
{
System.out.println("\t From Thread B: j= "+j);
if (j==3) stop();
}
System.out.println("Exit from B");
}
}
35
class C extends Thread
{
public void run()
{
for(int k=1;k<=5;k++)
{
System.out.println("\t From Thread C: k= +k);
if (k==1)
{
sleep(1000);
}
}
System.out.println(Exit from C);
}
}
36
class ThreadMethods
{
public static void main(String args[])
{
A threadA=new A();
B threadB=new B();
C threadC=new C();
System.out.println("Start Thread A");
threadA.start();
System.out.println("Start Thread B");
threadB.start();
System.out.println("Start Thread C");
threadC.start();
System.out.println("End of main thread");
}
}
37
Start thread A
Start thread B
Start thread C
From thread B: j=1
From thread B: j=2
From thread B: j=3
From thread A: i=1
From thread A: i=2
End of main thread
From thread C: k=1
From thread A: i=3
From thread A: i=4
From thread A: i=5
Exit from A
From thread C: k=2
From thread C: k=3
From thread C: k=4
From thread C: k=5
Exit from C
38
39
Using isAlive() and join()
Two ways exist to determine whether a thread has finished.
First, you can call isAlive( ) on the thread.
This method is defined by Thread, and its general form is:
final boolean isAlive( )
The isAlive( ) method returns true if the thread upon which it is
called is still running.
It returns false otherwise.
40
Contd..
While isAlive( ) is occasionally useful, the method
that you will more commonly use to wait for a thread
to finish is called join( ), shown here:
final void join( ) throws InterruptedException
This method waits until the thread on which it is called
terminates.
Its name comes from the concept of the calling thread waiting
until the specified thread joins it.
41
Thread Priority
In Java, each thread is assigned priority, which affects
the order in which it is scheduled for running. The
threads so far had same default priority
(NORM_PRIORITY) and they are served using FCFS
policy.
Java allows users to change priority:
ThreadName.setPriority(intNumber)
MIN_PRIORITY = 1
NORM_PRIORITY=5
MAX_PRIORITY=10
42
Thread Priority Example
class A extends Thread
{
public void run()
{
System.out.println("Thread A started");
for(int i=1;i<=4;i++)
{
System.out.println("\t From ThreadA: i= "+i);
}
System.out.println("Exit from A");
}
}
class B extends Thread
{ public void run()
{
System.out.println("Thread B started");
for(int j=1;j<=4;j++)
{
System.out.println("\t From ThreadB: j= "+j);
}
System.out.println("Exit from B");
}}
43
Thread Priority Example
class C extends Thread
{ public void run()
{ System.out.println("Thread C started");
for(int k=1;k<=4;k++)
{
System.out.println("\t From ThreadC: k= "+k);
}
System.out.println("Exit from C");
}}
class ThreadPriority
{ public static void main(String args[])
{
A threadA=new A();
B threadB=new B();
C threadC=new C();
threadC.setPriority(Thread.MAX_PRIORITY);
threadB.setPriority(threadA.getPriority()+1);
threadA.setPriority(Thread.MIN_PRIORITY);
System.out.println("Started Thread A");
threadA.start();
System.out.println("Started Thread B");
threadB.start();
System.out.println("Started Thread C");
threadC.start();
System.out.println("End of main thread"); } }
44
Start thread A
Start thread B
Start thread C
threadB started
From ThreadB: j= 1
From ThreadB: j= 2
threadC started
From ThreadC: k= 1
From ThreadC: k= 2
From ThreadC: k= 3
From ThreadC: k= 4
Exit from C
End of main thread
From ThreadB: j= 3
From ThreadB: j= 4
Exit from B
threadA started
From ThreadA: i= 1
From ThreadA: i= 2
From ThreadA: i= 2
From ThreadA: i= 2
Exit from A
Run 1
45
Accessing Shared Resources
Applications Access to Shared Resources need
to be coordinated.
Printer (two person jobs cannot be printed at the
same time)
Simultaneous operations on your bank account.
Can the following operations be done at the same
time on the same account?
Deposit()
Withdraw()
Enquire()
46
Online Bank: Serving Many Customers
and Operations
PC client
Internet Bank
Server
Local Area Network
Bank
Database
PD
A
47
class Callme
{
void call(String msg)
{
System.out.print("[" + msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable
{
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s)
{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
target.call(msg);
}
}
48
class Synch {
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
49
Here is the output produced by this
program:
Hello[Synchronized[World]
]
]
50
Solution 1
class Callme {
synchronized void call(String msg) {
...
}
}
After synchronized has been added to call( ), the
output of the program is as follows:
[Hello]
[Synchronized]
[World]
51
Solution 2
put calls to the methods defined by this class inside a synchronized
block.
This is the general form of the synchronized statement:
synchronized(object) {
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A
synchronized block ensures that a call to a method that is a member
of object occurs only after the current thread has successfully
entered objects monitor.
52
class Callme
{
void call(String msg)
{
System.out.print("[" + msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable
{
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s)
{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
synchronized(target) {
target.call(msg); }
}
}
53
class Synch {
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
54
Comparison
55