Chapter 4-Introduction To Multithreading
Chapter 4-Introduction To Multithreading
A program can be divided into a number of small processes. Each small process can be
addressed as a single thread (a lightweight process). You can think of a lightweight process as a
virtual CPU that executes code or system calls. You usually do not need to concern yourself with
lightweight processes to program with threads. Multithreaded programs contain two or more
threads that can run concurrently and each thread defines a separate path of execution. This
means that a single program can perform two or more tasks simultaneously. For example, one
thread is writing content on a file at the same time another thread is performing spelling check.
1. New : A thread begins its life cycle in the new state. It remains in this state until the
start() method is called on it.
2. Runnable : After invocation of start() method on new thread, the thread becomes
runnable.
3. Running : A thread is in running state if the thread scheduler has selected it.
4. Waiting : A thread is in waiting state if it waits for another thread to perform a task. In
this stage the thread is still alive.
5. Terminated : A thread enter the terminated state when it complete its task.
1
Jinka University- Department of Computer Science –2014 EC
Thread Priorities
Every thread has a priority that helps the operating system determine the order in which threads
are scheduled for execution. In java thread priority ranges between 1 to 10,
MIN-PRIORITY (a constant of 1)
MAX-PRIORITY (a constant of 10)
By default every thread is given a NORM-PRIORITY(5). The main thread always have NORM-
PRIORITY.
Note: Thread priorities cannot guarantee that a higher priority thread will always be executed
first than the lower priority thread. The selection of the threads for execution depends upon the
thread scheduler which is platform dependent.
Thread Class
Thread class is the main class on which Java's Multithreading system is based. Thread class,
along with its companion interface Runnable will be used to create and run threads for utilizing
Multithreading feature of Java.
Constructors of Thread class
1. Thread ( )
2. Thread ( String str )
3. Thread ( Runnable r )
4. Thread ( Runnable r, String str)
You can create new thread, either by extending Thread class or by implementing Runnable
interface. Thread class also defines many methods for managing threads. Some of them are,
Method Description
setName() to give thread a name
getName() return thread's name
getPriority() return thread's priority
isAlive() checks if thread is still running or not
join() Wait for a thread to end
run() Entry point for a thread
sleep() suspend thread for a specified time
start() start a thread by calling run() method
Some Important points to Remember
1. When we extend Thread class, we cannot override setName() and getName() functions,
because they are declared final in Thread class.
2. While using sleep(), always handle the exception it throws.
2
Jinka University- Department of Computer Science –2014 EC
Implementing the Runnable Interface
The easiest way to create a thread is to create a class that implements the runnable interface.
After implementing runnable interface , the class needs to implement the run() method, which is
of form,
public void run()
run() method introduces a concurrent thread into your program. This thread will end
when run() method terminates.
You must specify the code that your thread will execute inside run() method.
run() method can call other methods, can use other classes and declare variables just like
any other normal method.
class MyThread implements Runnable
{
public void run()
{
System.out.println("concurrent thread started running..");
}
}
class MyThreadDemo concurrent thread started running..
{
public static void main( String args[] )
{
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
}
}
To call the run() method, start() method is used. On calling start(), a new stack is provided to
the thread and run() method is called to introduce the new thread into the program.
Note: If you are implementing Runnable interface in your class, then you need to explicitly
create a Thread class object and need to pass the Runnable interface implemented class object as
a parameter in its constructor.
Extending Thread class
This is another way to create a thread by a new class that extends Thread class and create an
instance of that class. The extending class must override run() method which is the entry point
of new thread.
class MyThread extends Thread
{ concurrent thread started running..
public void run()
{
System.out.println("concurrent thread started running..");
}
}
3
Jinka University- Department of Computer Science –2014 EC
Class MyThreadDemo
{
public static void main( String args[] )
{
MyThread mt = new MyThread();
mt.start();
}
}
In this case also, we must override the run() and then use the start() method to run the thread.
Also, when you create MyThread class object, Thread class constructor will also be invoked, as
it is the super class, hence MyThread class object acts as Thread class object.
What if we call run() method directly without using start() method ?
In above program if we directly call run() method, without using start() method,
public static void main( String args[] )
{
MyThread mt = new MyThread();
mt.run();
}
Doing so, the thread won't be allocated a new call stack, and it will start running in the current
call stack, that is the call stack of the main thread. Hence Multithreading won't be there.
Can we Start a thread twice ?
No, a thread cannot be started twice. If you try to do so, IllegalThreadStateException will be
thrown.
public static void main( String args[] )
{
MyThread mt = new MyThread();
mt.start();
mt.start(); //Exception thrown
}
When a thread is in running state, and you try to start it again, or any method try to invoke that
thread again using start() method, exception is thrown.
Joining threads
Sometimes one thread needs to know when other thread is terminating. In java, isAlive() and
join() are two different methods that are used to check whether a thread has finished its
execution or not.
The isAlive() method returns true if the thread upon which it is called is still running otherwise
it returns false.
final boolean isAlive()
But, join() method is used more commonly than isAlive(). This method waits until the thread on
which it is called terminates.
final void join() throws InterruptedException
4
Jinka University- Department of Computer Science –2014 EC
Using join() method, we tell our thread to wait until the specified thread completes its execution.
There are overloaded versions of join() method, which allows us to specify time for which you
want to wait for the specified thread to terminate.
final void join(long milliseconds) throws InterruptedException
The main thread must always be the last thread to finish its execution. Therefore, we can use
Thread join() method to ensure that all the threads created by the program has been terminated
before the execution of the main thread.
Example of isAlive method
public class MyThread extends Thread
{
public void run()
{
System.out.println("r1 ");
r1 true true r1 r2 r2
try {
Thread.sleep(500);
}
catch(InterruptedException ie) { }
System.out.println("r2 ");
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
t2.start();
System.out.println(t1.isAlive());
System.out.println(t2.isAlive());
}
}
5
Jinka University- Department of Computer Science –2014 EC
In this above program two thread t1 and t2 are created. t1 starts first and after printing "r1" on
console thread t1 goes to sleep for 500 ms. At the same time Thread t2 will start its process and
print "r1" on console and then go into sleep for 500 ms. Thread t1 will wake up from sleep and
print "r2" on console similarly thread t2 will wake up from sleep and print "r2" on console. So
you will get output like r1 r1 r2 r2
Example of thread with join() method
public class MyThread extends Thread
{
public void run() r1 r2 r1 r2
{
System.out.println("r1 ");
try {
Thread.sleep(500);
}catch(InterruptedException ie){ }
System.out.println("r2 ");
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
try{
t1.join(); //Waiting for t1 to finish
}catch(InterruptedException ie){}
t2.start();
}
}
In this above program join() method on thread t1 ensures that t1 finishes it process before thread
t2 starts.
7
Jinka University- Department of Computer Science –2014 EC
start();
}
public void run()
{
fobj.display(msg);
}
}
public class Syncro
{
public static void main (String[] args)
{
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1= new Second (fnew,"new");
Second ss2 = new Second(fnew, "programmer");
}
}
In the above program, object fnew of class First is shared by all the three running threads(ss, ss1
and ss2) to call the shared method(void display). Hence the result is unsynchronized and such
situation is called Race condition.
Synchronized Keyword
To synchronize above program, we must synchronize access to the shared display() method,
making it available to only one thread at a time. This is done by using keyword synchronized
with display() method.
synchronized void display (String msg)
Using Synchronized block
If you have to synchronize access to an object of a class or you only want a part of a method to
be synchronized to an object then you can use synchronized block for it.
class First
{
public void display(String msg)
{
System.out.print ("["+msg); [welcome] [new] [programmer]
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]");
}
}
8
Jinka University- Department of Computer Science –2014 EC
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{
fobj = fp;
msg = str;
start();
}
public void run()
{
synchronized(fobj) //Synchronized block
{
fobj.display(msg);
}
}
}
public class Syncro
{
public static void main (String[] args)
{
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1= new Second (fnew,"new");
Second ss2 = new Second(fnew, "programmer");
}
}
Because of synchronized block this program gives the expected output.
In this example, there is no synchronization, so output is inconsistent. Let's see the example:
class Table{
void printTable(int n){//method not synchronized
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
} } }
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
} } }
10
Woldia University- Department of Computer Science --2012
public void run(){
t.printTable(5);
}
11
Woldia University- Department of Computer Science --2012
wait() tells calling thread to give up monitor and go to sleep until some other thread
enters the same monitor and call notify.
notify() wakes up a thread that called wait() on same object.
notifyAll() wakes up all the thread that called wait() on same object.
wait() sleep()
called from synchronized block no such requirement
monitor is released monitor is not released
gets awake when notify() or does not get awake when notify() or notifyAll() method
notifyAll() method is called. is called
not a static method static method
wait() is generally used on condition sleep() method is simply used to put your thread on
sleep.
Thread Pooling
Pooling is usually implemented by loop i.e to check some condition repeatedly. Once condition
is true appropriate action is taken. This waste CPU time.
Deadlock
Deadlock is a situation of complete Lock, when no thread can complete its execution because
lack of resources. In the above picture, Thread 1 is holding a resource R1, and need another
resource R2 to finish execution, but R2 is locked by Thread 2, which needs R3, which in turn is
locked by Thread 3. Hence none of them can finish and are stuck in a deadlock.
Example of deadlock
class Pen{}
12
Woldia University- Department of Computer Science --2012
class Paper{}
public class Write {
public static void main(String[] args)
{
final Pen pn =new Pen();
final Paper pr =new Paper();
Thread t1 = new Thread(){
public void run()
{
synchronized(pn)
{
System.out.println("Thread1 is holding Pen");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
synchronized(pr)
{ System.out.println("Requesting for Paper");
}
}
}
};
Thread t2 = new Thread(){
public void run()
{
synchronized(pr) {
System.out.println("Thread2 is holding Paper");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
synchronized(pn)
{ System.out.println("requesting for Pen"); }
}
}
};
t1.start();
t2.start();
}
}
13
Woldia University- Department of Computer Science --2012