Java Programming
Unit – 4
Multi Threading
Dr. Y. J. Nagendra Kumar
Professor of IT
Dean - Technology and Innovation Cell - GRIET
TABLE OF
CONTENTS
01 Creating Threads
02 Thread Life Cycle
03 Synchronization
04 Inter Thread Communication
Dr. Y. J. Nagendra Kumar - 2
Creating Threads
Dr. Y. J. Nagendra Kumar - 3
Multi Tasking
• There are two distinct types of multitasking:
1. Process-based
2. Thread-based.
• Process-based multitasking is the feature that allows our
computer to run two or more programs concurrently.
• In a Thread-based multitasking environment, a single program
can perform two or more tasks simultaneously.
Dr. Y. J. Nagendra Kumar - 4
Thread
• A multithreaded program contains two or more parts that can run
concurrently.
• Each part of such a program is called a thread, and each thread
defines a separate path of execution.
• Multithreading is a specialized form of multitasking.
• Multithreading enables us to write very efficient programs that
make maximum use of the CPU, because idle time can be kept to a
minimum.
Dr. Y. J. Nagendra Kumar - 5
Difference between Process and Thread
Process Thread
A Process is a program under execution. A Process A Thread is a single flow of execution and is a segment
contains many threads of a Program
Creation of new Process requires a new address Threads can be created in the same address space. It
space and resources saves memory space and OS resources
Processes have different code and data segments. Threads share the code and data segments i.e., if one
thread modifies a variable, all threads see the new value
of that variable
Processes are heavy weight components Threads are light weight components.
Communication between processes can be Communication between threads are very simple and
established using Inter Process Communication efficient.
mechanism. Ex: Inter Thread Communication
Ex: Sockets and pipes
Dr. Y. J. Nagendra Kumar - 6
Main Thread
• When a Java program starts up, one thread begins running immediately.
This is usually called the main thread of our program, because it is the one
that is executed when our program begins.
• The main thread is important for two reasons:
■ It is the thread from which other “child” threads will be spawned.
■ Often it must be the last thread to finish execution because it
performs various shutdown actions.
Dr. Y. J. Nagendra Kumar - 7
Main Thread Program
class CurrentThreadDemo
{ public static void main(String args[])
{ Thread t = [Link]();
[Link]("Current thread: " + t);
// change the name of the thread
[Link]("My Thread");
[Link]("After name change: " + t);
try
{ for(int n = 5; n > 0; n--)
{ [Link](n);
[Link](1000);
}
}
catch (InterruptedException e)
{ [Link]("Main thread interrupted");
}
}
}
Dr. Y. J. Nagendra Kumar - 8
• A reference to the current thread (the main thread, in this case) is
obtained by calling currentThread( ), and this reference is stored in
the local variable t.
• setName( ) to change the internal name of the thread.
• The argument to sleep( ) specifies the delay period in milliseconds.
• Notice the try/catch block around this loop. The sleep( ) method in
Thread might throw an InterruptedException.
• The name of the thread, its priority, and the name of its group.
Dr. Y. J. Nagendra Kumar - 9
Creating a Thread
• In the most general sense, we create a thread by
instantiating an object of type Thread.
• Java defines two ways
■ We can implement the Runnable interface.
■ We can extend the Thread class.
Dr. Y. J. Nagendra Kumar - 10
Implementing Runnable
• The easiest way to create a thread is to create a class that implements
the Runnable interface.
• To implement Runnable, a class need only implement a single method
called run( ), which is declared like this: public void run( )
• Inside run( ), we will define the code that constitutes the new thread.
• After we create a class that implements Runnable, we will instantiate
an object of type Thread from within that class.
Dr. Y. J. Nagendra Kumar - 11
Implementing Runnable
• Thread defines several constructors.
Thread(Runnable threadOb, String threadName)
• In this constructor, threadOb is an instance of a class that implements
the Runnable interface. This defines where execution of the thread
will begin. The name of the new thread is specified by threadName.
• After the new thread is created, it will not start running until you call
its start( ) Method
• void start( )
Dr. Y. J. Nagendra Kumar - 12
Runnable Interface Program
class NewThread implements Runnable class ThreadDemo
{ Thread t; { public static void main(String args[])
NewThread() { new NewThread();
{t = new Thread(this, "Demo Thread");
[Link]("Child thread: " + t); try
[Link](); { for(int i = 5; i > 0; i--)
} { [Link]("Main Thread: " + i);
public void run() [Link](1000);
{ try }
{ for(int i = 5; i > 0; i--)
{ }
[Link]("Child Thread: " + i); catch (InterruptedException e)
[Link](500); {
} [Link]("Main thread interrupted.");
} }
catch (InterruptedException e)
{[Link]("Child interrupted.");} [Link]("Main thread exiting.");
[Link]("Exiting child thread."); }
} }
}
Dr. Y. J. Nagendra Kumar - 13
Extending Thread
• The second way to create a thread is to create a new class
that extends Thread, and then to create an instance of that
class.
• The extending class must override the run() method, which
is the entry point for the new thread.
• It must also call start() to begin execution of the new thread.
Dr. Y. J. Nagendra Kumar - 14
Extending Thread Class Program
class NewThread1 extends Thread class ThreadDemo
{ { public static void main(String args[])
NewThread1() { new NewThread1();
{
[Link]("Child thread: " + this); try
start(); {
} for(int i = 5; i > 0; i--)
public void run() {
{ try [Link]("Main Thread: " + i);
{ for(int i = 5; i > 0; i--)
{ [Link](1000);
[Link]("Child Thread: " + i); }
[Link](500); }
} catch (InterruptedException e)
} {
catch (InterruptedException e)
{[Link]("Child interrupted.");} [Link]("Main thread interrupted.");
[Link]("Exiting child thread."); } [Link]("Main thread exiting.");
} }
} }
Dr. Y. J. Nagendra Kumar - 15
Creating Multiple Threads
• So far, we have been using only two threads: the main
thread and one child thread.
• However, our program can spawn as many threads as
it needs.
Dr. Y. J. Nagendra Kumar - 16
Creating Multiple Threads Program
class NewThread2 implements Runnable catch (InterruptedException e)
{ {
String name; [Link](name +"Interrupted");
Thread t; }
NewThread2(String threadname) [Link](name + " exiting.");
{ }
name = threadname; }
t = new Thread(this, name);
[Link]("New thread: " + t); class MultiThreadDemo
[Link](); {
} public static void main(String args[])
public void run() {
{ try new NewThread2("One");
{for(int i = 5; i > 0; i--) new NewThread2("Two");
{ new NewThread2("Three");
[Link](name + ": " + i);
[Link](1000); [Link]("Main thread exiting.");
} }
} }
Dr. Y. J. Nagendra Kumar - 17
Thread Priorities
• Thread priorities are used by the thread scheduler to decide when
each thread should be allowed to run.
• A higher-priority thread can also preempt a lower-priority one.
• To set a thread’s priority, use the setPriority( ) method, which is a
member of Thread.
• final void setPriority(int level)
Here, level specifies the new priority setting for the calling thread.
Dr. Y. J. Nagendra Kumar - 18
Thread Priorities
• The value of level must be within the range MIN_PRIORITY and
MAX_PRIORITY. Currently, these values are 1 and 10, respectively.
• To return a thread to default priority, specify NORM_PRIORITY,
which is currently 5. These priorities are defined as final variables
within Thread.
• We can obtain the current priority setting by calling the
getPriority( ) method of Thread, shown here:
final int getPriority( )
Dr. Y. J. Nagendra Kumar - 19
Thread Priorities Program
class A extends Thread class C extends Thread
{ public void run() {
{ public void run()
for (int i=1;i<=5; i++) {
{ for (int k=1;k<=5; k++)
[Link]("\tFrom Thread A : i="+i); {
} [Link]("\tFrom Thread C : K="+k);
[Link]("Exit From A "); }
} [Link]("Exit From C ");
} }
class B extends Thread }
{ public void run()
{
for (int j=1;j<=5 ;j++)
{
[Link]("\tFrom Thread B : j="+j);
}
[Link]("Exit From B ");
}
}
Dr. Y. J. Nagendra Kumar - 20
Thread Priorities Program
class ThreadPriority
{ public static void main(String []args)
{ A a=new A();
B b=new B();
C c=new C();
[Link](Thread.MAX_PRIORITY);
[Link](Thread.NORM_PRIORITY);
//[Link]([Link]()-2));
[Link](Thread.MIN_PRIORITY);
//[Link]([Link]()+1));
[Link]("Start Thread C ");
[Link]();
[Link]("Start Thread B ");
[Link]();
[Link]("Start Thread A ");
[Link]();
[Link]("End of Main Thread ");
}
}
Dr. Y. J. Nagendra Kumar - 21
Thread Life Cycle
Dr. Y. J. Nagendra Kumar - 22
Thread Life Cycle New Born State
Start Stop
Stop
Running State Runnable State Dead State
Yield
Suspend( ) resume( )
wait( ) notify( ) Stop
sleep( )
Blocked State
Dr. Y. J. Nagendra Kumar - 23
New born State
• When we create a thread object then the thread is in New born
state.
• It has two alternatives
New Born
– Schedule it for running using start() method State
Start Stop
– Kill it using stop() method
Runnable Dead
State State
Dr. Y. J. Nagendra Kumar - 24
Runnable State
• It means thread is ready for execution and is waiting for the
availability of the processor. If all threads have equal priority then
they are given time slots for execution in Round Robin fashion (FIFO)
• We can move the threads from running state to runnable state by
giving yield() command.
Yield( )
t1 t2 t3 t4
Running State Runnable State
Dr. Y. J. Nagendra Kumar - 25
Running State
● It means the processor has given its time to the thread for its
execution. The thread runs until it relinquishes the control on its
own or it is preempted by a higher priority thread
Blocked State
• A thread is said to be blocked when it is prevented from entering
into runnable state and subsequently running state. It is also
called “Not runnable state”
Dr. Y. J. Nagendra Kumar - 26
Suspend()
• A thread can be suspended using suspend() method
suspend( )
resume( )
t t t
Running State Runnable State Blocked state
• A suspended thread can be received by using resume() method
Dr. Y. J. Nagendra Kumar - 27
Sleep()
• We can put a thread into sleep mode for a specified time period
using sleep() method
sleep( )
after n sec
t t t
Running State Runnable State Blocked state
wait()
• The thread has to wait until some event occurs. This is done using a
wait() method. The thread can be scheduled to run again using
notify() command
Dr. Y. J. Nagendra Kumar - 28
wait( )
notify( )
t t t
Running State Runnable State Blocked state
Dead State
• A running thread ends its life when it is completed its execution is
called “ Natural Death” otherwise we can kill using a stop() message
then it is called “Preemptive death”
Dr. Y. J. Nagendra Kumar - 29
Thread Life Cycle Program
class A extends Thread class C extends Thread
{ public void run() { public void run()
{ for (int i=1;i<=5; i++) { for (int k=1;k<=5; k++) {
{
if(i==1) yield(); [Link]("\tFrom Thread C : K="+k);
[Link]("\tFrom Thread A : i="+i); if(k==1) try { sleep(1000); }
} catch(Exception e) {}
[Link]("Exit From A "); } [Link]("Exit From C ");
} }
}
class B extends Thread }
{ public void run() class ThreadMethods
{ for (int j=1;j<=5 ;j++) { public static void main(String []args)
{ {
[Link]("\tFrom Thread B : j="+j); [Link]("Start Thread A "); new A().start();
if(j==3) stop();
[Link]("Start Thread B "); new B().start();
}
[Link]("Start Thread C "); new C().start();
[Link]("Exit From B ");
} [Link]("End of Main Thread ");
} } }
Dr. Y. J. Nagendra Kumar - 30
Synchronization
Dr. Y. J. Nagendra Kumar - 31
Synchronization
• One thread may try to read a record from a file while another is still
writing to the same file. This time we may get strange results.
• Java enables us to overcome this problem using a technique known as
Synchronization
• When two or more threads need access to a shared resource, they need
some way to ensure that the resource will be used by only one thread
at a time.
• The process by which this is achieved is called synchronization.
Dr. Y. J. Nagendra Kumar - 32
Synchronization
• Key to synchronization is the concept of the monitor (also called a
semaphore).
• A monitor is an object that is used as a mutually exclusive lock, or
mutex. Only one thread can own a monitor at a given time.
• When a thread acquires a lock, it is said to have entered the monitor. All
other threads attempting to enter the locked monitor will be suspended
until the first thread exits the monitor.
• These other threads are said to be waiting for the monitor.
Dr. Y. J. Nagendra Kumar - 33
Synchronized Method
• When we declare a method synchronized, Java creates a “monitor” and hands
it over to the thread that calls the method first time.
• As long as the thread holds the monitor, no other thread can enter the
synchronized section of code.
• A monitor is like a key and the thread that holds the key can only open the
lock.
• This is the general form of the synchronized statement:
synchronized method()
{
// statements to be synchronized
} Dr. Y. J. Nagendra Kumar - 34
Synchronization Program
class Callme public void run()
{ void call(String msg) {
{ [Link]("[" + msg); synchronized(target)
try {
{ [Link](1000); } [Link](msg);
catch (InterruptedException e) }
}
{[Link]("Interrupted"); } }
[Link]("]"); class Synch1
} { public static void main(String args[])
} {
class Caller implements Runnable Callme target = new Callme();
{ String msg; Callme target;
Thread t; Caller ob1 = new Caller(target, "Hello");
public Caller(Callme targ, String s)
{ target = targ; Caller ob2 = new Caller(target, "Synchronized");
msg = s;
t = new Thread(this); Caller ob3 = new Caller(target, "World");
[Link](); }
} }
Dr. Y. J. Nagendra Kumar - 35
Suspend - Resume
• The suspend() method of thread class puts the thread from running
to waiting state.
• This method is used if you want to stop the thread execution and
start it again when a certain event occurs.
• This method allows a thread to temporarily cease execution. The
suspended thread can be resumed using the resume() method.
Dr. Y. J. Nagendra Kumar - 36
Suspend – Resume Program
class NewThread implements Runnable catch (InterruptedException e)
{ String name; Thread t; { [Link](name + " interrupted.");
NewThread(String threadname) }
{ name = threadname; [Link](name + " exiting.");
t = new Thread(this, name); }
[Link]("New thread: " + t); }
[Link](); class SuspendResume
} { public static void main(String args[])
public void run() {NewThread ob1 = new NewThread("One");
{ try NewThread ob2 = new NewThread("Two");
{ try
for(int i = 15; i > 0; i--) { [Link](1000);
{ [Link]();
[Link](name + ": " + i); [Link]("Suspending thread One");
[Link](200); [Link](1000);
} [Link]();
}
Dr. Y. J. Nagendra Kumar - 37
Suspend – Resume Program
[Link]("Resuming thread One"); try {
[Link](); [Link]("Waiting for threads to finish.");
[Link]("Suspending thread Two"); [Link]();
[Link](1000); [Link]();
[Link](); }
[Link]("Resuming thread Two"); catch (InterruptedException e)
} {
catch (InterruptedException e) [Link]("Main thread Interrupted");
{ }
[Link]("Main thread Interrupted"); [Link]("Main thread exiting.");
} }
}
Dr. Y. J. Nagendra Kumar - 38
Inter Thread Communication
Dr. Y. J. Nagendra Kumar - 39
Interthread Communication
• One thread is producing some data and another is consuming it.
• The producer has to wait until the consumer is finished before it
generates more data.
• Java includes an elegant interprocess communication mechanism via
the wait( ), notify( ), and notifyAll( ) methods. These methods are
implemented as final methods in Object.
• All three methods can be called only from within a synchronized
context.
Dr. Y. J. Nagendra Kumar - 40
Interthread Communication
• wait( ) tells the calling thread to give up the monitor and go to sleep until
some other thread enters the same monitor and calls notify( ).
final void wait( ) throws InterruptedException
• notify( ) wakes up the first thread that called wait( ) on the same object.
final void notify( )
• notifyAll( ) wakes up all the threads that called wait( ) on the same
[Link] highest priority thread will run first.
final void notifyAll( )
Dr. Y. J. Nagendra Kumar - 41
Producer Consumer Program
class Q synchronized void put(int n)
{ int n; {
boolean valueSet = false; if(valueSet)
{
synchronized int get() try
{ if(!valueSet) { wait();
{ try }
{ wait(); }
catch(InterruptedException e) catch(InterruptedException e)
{ {
[Link](“Exception caught"); [Link]("InterruptedException
} caught");
} }
}
[Link]("Got: " + n); this.n = n;
valueSet = false; valueSet = true;
notify(); [Link]("Put: " + n);
return n; notify();
} }
}
Dr. Y. J. Nagendra Kumar - 42
Producer Consumer Program
class Producer implements Runnable public void run()
{ Q q; {
Producer(Q q) while(true)
{ this.q = q; { [Link]();
new Thread(this, "Producer").start(); }
} }
public void run() }
{ int i = 0;
while(true) class PC1
{ [Link](i++); {
} public static void main(String args[])
} {
} Q q = new Q();
class Consumer implements Runnable
{ Q q; new Producer(q);
Consumer(Q q) new Consumer(q);
{ this.q = q;
new Thread(this, [Link]("Press Control+C to stop.");
"Consumer").start(); }
} }
Dr. Y. J. Nagendra Kumar - 43
Daemon Threads
• Java treats threads as User threads or Daemon threads
• User threads are the default. When main thread terminates,
the JVM checks to see if any other user thread is running.
• If so, JVM does not terminate the application. On the other
hand if JVM detects only Daemon threads the application
terminates
Dr. Y. J. Nagendra Kumar - 44
Daemon Threads
● Daemon threads are designed as low level background threads that
perform useful work. One example of Daemon thread is the “Garbage
Collector thread”
● To create a Daemon thread call setDaemon method with a boolean
true argument value i.e., setDaemon(true)
● To determine whether a thread object is associated with a Daemon
thread call isDaemon(). It returns boolean value T/F
Dr. Y. J. Nagendra Kumar - 45
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 shown here:
○ final boolean isAlive( )
● The isAlive( ) method returns true if the thread upon which it is
called is still running. It returns false otherwise.
Dr. Y. J. Nagendra Kumar - 46
Using isAlive() and join
• While isAlive( ) is occasionally useful, the method that we 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.
Dr. Y. J. Nagendra Kumar - 47
isAlive() and join() Program
class NewThread4 implements Runnable
{ String name; Thread t;
NewThread4(String threadname)
{ name = threadname;
t = new Thread(this, name);
[Link]("New thread: " + t);
[Link]();
}
public void run()
{ try
{ for(int i = 5; i > 0; i--)
{ [Link](name + ": " + i);
[Link](1000); }
}
catch (InterruptedException e)
{ [Link](name + " interrupted."); }
[Link](name + " exiting.");
}
}
Dr. Y. J. Nagendra Kumar - 48
isAlive() and join() Program
class isalivejoin
{ public static void main(String args[])
{ NewThread4 ob1 = new NewThread4("One");
NewThread4 ob2 = new NewThread4("Two");
NewThread4 ob3 = new NewThread4("Three");
[Link]("Thread One is alive: "+ [Link]());
[Link]("Thread Two is alive: "+ [Link]());
[Link]("Thread Three is alive: "+ [Link]());
try
{ [Link]("Waiting for threads to finish.");
[Link]();[Link]();[Link]();
}
catch (InterruptedException e)
{ [Link]("Main thread Interrupted"); }
[Link]("Thread One is alive: "+ [Link]());
[Link]("Thread Two is alive: "+ [Link]());
[Link]("Thread Three is alive: "+ [Link]());
[Link]("Main thread exiting.");
}
}
Dr. Y. J. Nagendra Kumar - 49
End of Unit IV