multithreaded programming
multithreaded programming
Unit 4:
Multithreaded Programming: The Java thread model, the main thread, creating thread, c r e a t i n g
multiple threads, using isAlive() and join(), Thread priorities, synchronization, inter t h r e a d
communication, suspending resuming and stopping threads.
Multithreading:
A Thread is a very light-weighted process, or we can say the smallest part of the process that a l l o w s
a program to operate more efficiently by running multiple tasks simultaneously.
When multiple threads are executed in parallel at the same time, this process is k n o w n
as Multithreading.
Multithreading is a Java feature that allows concurrent execution of two or more parts of a program
for maximum utilization of CPU or it is a process of executing multiple threads simultaneously.
Each part of such a program is called a thread.
Multithreading is a specialized form of multitasking. Multitasking:
Multitasking is a process of executing multiple tasks simultaneously. We use multitasking t o
utilize the CPU.
Multitasking can be achieved in two ways:
Process-based Multitasking (Multiprocessing)
Thread-based Multitasking (Multithreading)
1) Process-based Multitasking (Multiprocessing)
Each process has an address in memory or each process allocates a separate memory area.
A process is heavyweight.
Cost of communication between the process is high.
Switching from one process to another requires some time for saving and loading registers,
memory maps, updating lists, etc.
Runnable / Ready:
When a thread calls start( ) method, then the thread is said to be in the Runnable state. This state is
also known as a Ready state(under execution).
e.g.
t1.start( );
Running state:
When a thread calls run( ) method, then the thread is said to be Running. The run( ) method of a
thread called automatically by the start( ) method.
Blocked / Waiting:
A thread in the Running state may move into the blocked state when it is waiting for resources o r
due to various reasons like sleep( ) method called, wait( ) method called, suspend( ) method c a l l e d ,
and join( ) method called, etc.
When a thread is in the blocked or waiting state, it may move to Runnable state due to reasons l i k e
sleep time completed, waiting time completed, notify( ) or notifyAll( ) method called, resume( )
method called, etc.
e.g.
Thread.sleep(1000); wait(1000);
wait(); suspend();
run(): - The run() method moves the thread into running state. It is executed only after the start()
method has been executed. The general syntax of this method is as follows:
Syntax:
public void run()
sleep(): It suspends or pause currently executing thread for the specified amount of time i n
milliseconds.
Syntax:
public static void sleep(long milliseconds) throws InterruptedException
This method throws InterruptedException and must be used within a try-catch block.
join(): The join() method is used to make a thread wait for another thread to terminate its process.
Syntax:
public final void join() throw InterruptedException
This method throws InterruptedException and must be used within a try-catch block.
getName(): This method returns the name of the thread. The return type of this method is String.
Syntax:
public final String getName()
setName(): The setName() method is used to set the name of a thread. It takes an argument o f
type String.
Syntax:
public final void setName(String name)
getPriority(): The getPriority() method returns the priority of a thread. It returns priority in t h e
form of an integer value ranging from 1 to 10. The maximum priority is 10, t h e
minimum priority is 1, and normal priority is 5.
Syntax:
public final int getPriority() // Return type is an integer.
setPriority(): This method is used to set the priority of a thread. It accepts an integer value as a n
argument.
Syntax:
public final void setPriority(int newPriority)
isAlive(): This method is used to check the thread is alive or not. It returns a boolean value ( t r u e
or false) that indicates thread is running or not. The isAlive() method is final and native.
Syntax:
public final native boolean isAlive()
Syntax:
Static Thread currentThread()
The method returns a reference to the thread in which it is called.
Output:
My Thread: Thread[main, 5, main]
After name change: Thread[My new thread, 5, ma i n]
i=1
i=2
i=3 i=4 i=5
Creating a Thread:
There are two ways to create Threads in :
By extending Thread Class
By implementing a Runnable interface
run() can call other methods, use other classes and declare variables, just like main thread can. T h e
only difference is that run() establishes the entry point for another concurrent thread of execution.
class MyThread
{
public static void main(String r[])
{
new NThread(“Child Thread”); //create new thread
try
{
for(int i=1;i<=5;i++)
{
System.out.println(“Main Thread:”+i);
Thread.sleep(1000);
}
}
catch(InterruptedException e)
{
System.out.println(“Interrupted Main Thread:”);
}
System.out.println(“Exiting Main Thread”);
}
}
Output:
Child Thread: Thread[Child Thread,5,main] Main
Thread: 1
Child Thread: 1
Main Thread: 2
Child Thread: 2
-
-
Main Thread: 5
Child Thread: 5
Exiting Main T h r e a d
Exiting Child Thread
class MyThread
{
public static void main(String r[])
{
new NThread(); //create new thread
try
{
for(int i=1;i<=5;i++)
{
System.out.println(“Main Thread:”+i);
Thread.sleep(1000);
}
}
catch(InterruptedException e)
{
System.out.println(“Interrupted Main Thread:”);
}
System.out.println(“Exiting Main Thread”);
}
}
Output:
Child Thread: Thread[Child Thread,5,main] Main
Thread: 1
Child Thread: 1
Main Thread: 2
Child Thread: 2
-
-
Main Thread: 5
Child Thread: 5 Exiting Main Thread Exiting Child
Thread
To perform two tasks, we can create two threads and attach them to two tasks. Hence, c r e a t i n g
multiple threads in Java programming helps to perform more than one task simultaneously.
Creating more than one thread to perform multiple tasks is called multithreading in Java. I n
multiple threading programming, multiple threads are executing simultaneously that improves t h e
performance of CPU because CPU is not idle if other threads are waiting to get some resources.
Multiple threads share the same address space in the heap memory. Therefore, it is good t o
create multiple threads to execute multiple tasks rather than creating multiple processes.
Task1
Thread1
Processor
Task2 Thread2
Program
try
{
Thread.sleep(10000);
}
catch(InterruptedException e)
{
System.out.println(“Interrupted Main Thread:”);
}
System.out.println(“Exiting Main Thread”);
}
}
Output:
New Thread: Thread[First,5,main] New Thread:
Thread[Second,5,main] New Thread:
Thread[Third,5,main] First : 1
Second : 1
Third : 1
First : 2
Second : 2
Third : 2
-
-
-
First : 5
Second : 5
Third : 5
// Create two objects of Thread class and pass two objects as parameter to constructor of
// Thread class.
Thread t1 = new Thread(ot1); Thread t2 = new Thread(ot2); t1.start();
t2.start();
}
}
Output:
Cut the ticket : 1
Show your seat number : 1 Show your seat number : 2 Cut the ticket : 2
Show your seat number : 3 Cut the ticket : 3
Show your seat number : 4 Cut the ticket : 4
Show your seat number : 5 Cut the ticket : 5
The isAlive() method of Thread class tests if the thread is alive. A thread is considered alive w h e n
the start() method of Thread class has been called and the thread is not yet d e a d .
The isAlive() method returns true if the thread upon which it is called is still running and n o t
finished otherwise it returns false.
Syntax:
public final boolean isAlive()
join() method:
The join() method is provided by the java.lang.Thread class that permits one thread to wait u n t i l
the other thread to finish its execution.
When the join() method is invoked, the current thread stops its execution and the thread goes i n t o
the wait state.
The current thread remains in the wait state until the thread on which the join() method is invoked
has achieved its dead state. If interruption of the thread occurs, then it throws the
InterruptedException.
Syntax:
public final void join() throws InterruptedException
Output:
Start End Start End
class MyThread
{
public static void main(String[] r)
{
NThread ob1=new NThread(“First:”); NThread ob2=new
NThread(“Second:”);
System.out.println(“Thread First is isAlive:”+ob1.t.isAlive());
System.out.println(“Thread Second is isAlive:”+ob2.t.isAlive());
Output:
New Thread:Thread[First,5,main] New
Thread:Thread[Second,5,main] Thread First is isAlive: true
Thread Second is isAlive: true First:1
Second:1
First:2 Second:2
-
-
-
First:5 Second:5 Exiting:First Exiting:Second Main Exiting
Thread Priorities:
Each thread has a priority. Thread priority is a number that is assigned to a thread that is used b y
thread scheduler to decide which thread should be allowed to execute.
Thread priorities are represented by a number between 1 and 10. We can get and set the priority
of a Thread.
The thread with highest priority is selected by the scheduler to be executed first. A higher p r i o r i t y
thread can also pre-empt a lower priority one(known as preemptive scheduling). When a l o w e r
priority thread is running and a higher priority thread resumes, it will pre-empt the lower p r i o r i t y
thread.
However, thread priorities cannot guarantee the order in which threads execute and are very m u c h
platform dependent.
The default priority of thread is 5. The Thread class in Java provides priority constants to define
the priority of a thread:
MIN_PRIORITY: Specifies the minimum priority that a thread can have. (Priority 1)
NORM_PRIORITY: Specifies the default priority that a thread is assigned. (Priority 5)
MAX_PRIORITY: Specifies the maximum priority that a thread can have. (Priority 10)
Thread scheduler selects the thread for execution on First-come, First-serve basis. The threads
having equal priorities share the processor on First-come, First-serve basis.
2. setPriority() Method: This method is used to set the priority of a thread, it accepts the priority
value and updates an existing priority with the given priority.
Syntax:
final int getPriority();
Output:
Priority: 5 Name:New Thread
Thread[New Thread, 5, main]
Output:
Priority: 8 Name:New Thread
Thread[New Thread, 5, main]
//Program in Java for Thread prioirties
class NThread implements Runnable
{
long a=0; boolean r=true; Thread t; NThread(int
p)
{
T=new Thread(this); t.setPriority(p); t.start();
}
public void run()
{
while(r)
a++;
}
public void stop()
{
r=false;
}
}
class MyThread
{
public static void main(String[] r)
{
NThread ob1=new NThread(4); NThread
ob2=new NThread(8); try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
ob1.stop();
ob2.stop();
System.out.println(“Low Priority:”+ob1.a);
System.out.println(“High Priority:”+ob2.a);
}
}
Synchronization:
Synchronization is a mechanism used to control access to shared resources b y
multiple threads. It ensures that only one thread can access a shared resource at a
time.
It is the capability to control the access of multiple threads to any shared resource.
Synchronization is a better option where we want to allow only one thread to a c c e s s
the shared resource.
In the multithreading concept, multiple threads try to access the shared resources a t
a time to produce inconsistent results.
Synchronization is necessary for reliable communication between threads.
Mutual Exclusive helps keep threads from interfering with one another while sharing
data. It can be achieved by using the following three ways:
By Using Synchronized Method
By Using Synchronized Block
Synchronized Method:
In Java, we can declare entire methods as synchronized which prevent multiple
threads from accessing the method simultaneously.
If we declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the l o c k
for that object and release it when the thread completes its task.
class MyThread
{
public static void main(String r[])
{
Table ot=new Table();
NThread1 ob1=new NThread1(ot);
NThread2 ob2=new NThread2(ot);
ob1.start();
ob2.start();
}
}
Output:
5
10
10
20
15
30
-
-
-
-
//Understanding the problem with synchronized method
class Table
{
Synchronized void pTable(int n) //not synchronized method
{
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
}
try
{
Thread.sleep(500);
}
catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
}
Output:
5
10
15
20
25
30
10
20
30
40
50
wait() method:
wait() method in Java notifies the current thread to give up the monitor (lock) and to
go into sleep state until another thread wakes it up by calling notify() method. This
method throws InterruptedException.
Syntax:
public final void wait(long millisecond) throws InterruptedException
notify() method:
The notify() method wakes up a single thread that called wait() method on the same
object. If more than one thread is waiting, this method will awake one of them.
Syntax:
public final void notify()
notifyAll() method:
The notifyAll() method is used to wake up all threads that called wait() method o n
the same object. The thread having the highest priority will run first.
Syntax:
public final void notifyAll()
e.g.
public class A
{
int i;
synchronized void deliver(int i)
{
this.i = i;
System.out.println("Data Delivered: " +i);
}
synchronized int receive()
{
System.out.println("Data Received: " + i ) ;
return i;
}
}
public class Thread1 extends Thread
{
A ob; Thread1(A ob)
{
this.ob = ob;
}
public void run()
{
for(int j = 1; j <= 5; j++)
{
obj.deliver(j);
}
}
}
public class Thread2 extends Thread
{
A ob; Thread2(A ob)
{
this.ob = ob;
}
public void run()
{
for(int k = 0; k <= 5; k++)
{
obj.receive();
}
}
}
public class MThread
{
public static void main(String[] args)
{
A ob = new A();
Thread1 t1 = new Thread1(obj);
Thread2 t2 = new Thread2(obj);
t1.start();
t2.start();
}
}
Output:
Data Delivered: 1
Data Delivered: 2
Data Delivered: 3
Data Delivered: 4
Data Delivered: 5
Data Received: 5
Data Received: 5
Data Received: 5
Data Received: 5
Data Received: 5
Data Received: 5
//Program using wait() and notify() method to establish the communication
//between two threads.
public class A
{
int i;
boolean flag = false; // flag will be true when data production is o v e r .
synchronized void deliver(int i)
{
if(flag) try
{
wait(); // Wait till a notification is received from Thread2
}
catch(InterruptedException e)
{
System.out.println(e);
}
this.i = i;
flag = true; // When data production is over, it will store true into f l a g .
System.out.println("Data Delivered: " +i);
notify(); // When data production is over, it will notify Thread2 to use it.
}
synchronized int receive()
{
if(!flag) try
{
wait(); // Wait till a notification is received from Thread1.
}
catch(InterruptedException e)
{
System.out.println(ie);
}
System.out.println("Data Received: " + i);
flag = false; // It will store false into flag when data is received. notify(); // When
data received is over, it will notify Thread1 to produce next data. return i;
}
}
public class Thread1 extends Thread
{
A ob;
Thread1(A ob)
{
this.ob = ob;
}
public void run()
{
for(int j = 1; j <= 5; j++)
{
ob.deliver(j);
}
}
}
public class Thread2 extends Thread
{
A ob;
Thread2(A ob)
{
this.ob = ob;
}
public void run()
{
for(int k = 0; k <= 5; k++) { obj.receive();
}
}
}
Output:
Data Delivered: 1
Data Received: 1
Data Delivered: 2
Data Received: 2
Data Delivered: 3
Data Received: 3
Data Delivered: 4
Data Received: 4
Data Delivered: 5
Data Received: 5
1. In this example program, wait() and notify() methods are called inside deliver()
and receive() method. Both methods enable Thread1 to notify Thread2 a f t e r
producing data and wait until Thread2
complete using.
2. In the same way, Thread2 after using data notifies Thread1 and waits u n t i l
Thread1 produces and delivers the next data. Thus, the output comes in a
synchronized form.
3. If the flag is true, Thread2 takes data from Thread1 and use it. When Thread1 i s
busy producing data, now and then Thread2 will check flag is true or not.
If the flag shows false, then Thread2 will wait for the object until it receives a
notification from a notify() method.
When the data production is over, Thread1 will send a notification immediately t o
Thread2 to receive data. In this way, Thread1 and Thread2 communicate with e a c h
other efficiently.
Suspending, Resuming and Stopping threads:
suspend() method:
The suspend() method is used to suspend the thread temporarily. It will g e t
suspended until resumed in the program. A suspended thread can be resumed u s i n g
the resume() method. This method is used if we want to stop the thread execution
and start it again when a certain event occurs. The method temporarily c e a s e
execution.
Syntax
public final void suspend()
e.g.
class Mythread extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
try
{
sleep(500); System.out.println(Thread.currentThread().getName());
}
Catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
}
}
public static void main(String[] r)
{
//creating threads
MyThread ob1=new MyThread(); MyThread ob2=new MyThread();
MyThread ob3=new MyThread(); ob1.start();
ob2.start(); ob2.suspend();
// ob3.stop();
ob3.start();
//ob2.resume();
}
}
resume() method:
The resume() method is only used with suspend() method, to resume a thread w h i c h
was suspended using the suspend() method. This method allows the suspended
thread to start again.
Syntax
public final void resume()
ob2.resume();
stop() method:
The method terminates the thread execution. Once a thread is stopped, it cannot b e
resumed by start() method.
Syntax
public final void stop()
ob3.stop();