Multithreading
Multithreading
o Process-based Multitasking(Multiprocessing)
o
o Thread-based Multitasking(Multithreading)
o
Note:
At a time one thread is executed only.
new,
runnable,
non-runnable and
terminated.
2) Runnable
The thread is in runnable state after invocation of start()
method, but the thread scheduler has not selected it to be
the running thread.
3) Running
The thread is in running state if the thread scheduler has
selected it.
4) Non-Runnable (Blocked)
This is the state when the thread is still alive, but is
currently not eligible to run.
5) Terminated
A thread is in terminated or dead state when its run()
method exits.
Thread class:
Thread class provide constructors and methods to create
and perform operations on a thread .
Thread class extends Object class and implements
Runnable interface.
Runnable interface:
The Runnable interface should be implemented by any
class whose instances are intended to be executed by a
thread.
Runnable interface have only one method named run().
1. public void run():
Starting a thread:
start() method of Thread class is used to start a newly
created thread.
It performs following tasks:
o A new thread starts(with new callstack).
o The thread moves from New state to the Runnable
state.
o When the thread gets a chance to execute, its target
run() method will run.
1) Java Thread Example by extending Thread class
class Multi extends Thread
{
public void run()
{
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
Output:
thread is running...
or
1
1
2
2
3
3
4
4
public class TestThreadTwice1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestThreadTwice1 t1=new TestThreadTwice1();
t1.start();
t1.start();
}
}
running
Exception in thread "main"
java.lang.IllegalThreadStateExcept
ion
class TestCallRun1 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestCallRun1 t1=new TestCallRun1();
t1.run();//fine, but does not start a separate call stack
}
}
Output:running...
Problem if you direct call run() method
class TestCallRun2 extends Thread{
public void run(){
for(int i=1;i<5;i++){
try{Thread.sleep(500);}catch(InterruptedException e)
{System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[]){
TestCallRun2 t1=new TestCallRun2();
TestCallRun2 t2=new TestCallRun2();
t1.run();
t2.run();
}
}
Output:1
2
3
4
5
1
2
3
4
5
Syntax:
public void join()throws InterruptedException
Output:1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
class TestJoinMethod3 extends Thread{
public void run(){
System.out.println("running...");
}
public static void main(String args[]){
TestJoinMethod3 t1=new TestJoinMethod3();
TestJoinMethod3 t2=new TestJoinMethod3();
System.out.println("Name of t1:"+t1.getName());
System.out.println("Name of t2:"+t2.getName());
System.out.println("id of t1:"+t1.getId());
t1.start();
t2.start();
t1.setName("pradip");
System.out.println("After changing name of t1:"+t1.getNa
me());
}
}
Output:Name of t1:Thread-0
Name of t2:Thread-1
id of t1:8
running...
After changling name of t1:Sonoo Jaiswal
running...
Syntax:
class TestJoinMethod4 extends Thread{
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String args[]){
TestJoinMethod4 t1=new TestJoinMethod4();
TestJoinMethod4 t2=new TestJoinMethod4();
t1.start();
t2.start();
}
}
Output:Thread-0
Thread-1
thread-0,
thread-1
and so on.
Current Thread
The currentThread() method returns a reference of
currently executing thread.
public static Thread currentThread()
Its life depend on the mercy of user threads i.e. when all
the user threads dies, JVM terminates this thread
automatically.
You can see all the detail by typing the jconsole in the
command prompt.
public class TestDaemonThread1 extends Thread{
public void run(){
if(Thread.currentThread().isDaemon()){//checking for dae
mon thread
System.out.println("daemon thread work");
}
else{
System.out.println("user thread work");
}
}
public static void main(String[] args){
TestDaemonThread1 t1=new TestDaemonThread1();//crea
ting thread
TestDaemonThread1 t2=new TestDaemonThread1();
TestDaemonThread1 t3=new TestDaemonThread1();
t1.setDaemon(true);//now t1 is daemon thread
t1.start();//starting threads
t2.start();
t3.start();
}
}
Output
Note:
If you want to make a user thread as Daemon, it must
not be started otherwise it will throw
IllegalThreadStateException.
File: MyThread.java
class TestDaemonThread2 extends Thread{
public void run(){
System.out.println("Name: "+Thread.currentThread().getN
ame());
System.out.println("Daemon: "+Thread.currentThread().isD
aemon());
}
public static void main(String[] args){
TestDaemonThread2 t1=new TestDaemonThread2();
TestDaemonThread2 t2=new TestDaemonThread2();
t1.start();
t1.setDaemon(true);//will throw exception here
t2.start();
}
}
Output:
exception in thread main:
java.lang.IllegalThreadStateException
Java Thread Pool
Java Thread pool represents a group of worker threads
that are waiting for the job and reuse many times.
File: WorkerThread.java
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable {
private String message;
public WorkerThread(String s){
this.message=s;
}
public void run() {
System.out.println(Thread.currentThread().getName()
+" (Start) message = "+message);
processmessage();//call processmessage method that s
leeps the thread for 2 seconds
System.out.println(Thread.currentThread().getName()
+" (End)");//prints thread name
}
private void processmessage() {
try {
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
File: JavaThreadPoolExample.java
public class TestThreadPool
{
public static void main(String[] args)
{
ExecutorService executor = Executors.newFixedThreadP
ool(5);
//creating a pool of 5 threads
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);//calling execute method
of ExecutorService
}
executor.shutdown();
while (!executor.isTerminated()) { }
System.out.println("Finished all threads");
}
}
Output:
In such way,
we can suspend,
Note:
java.lang.ThreadGroup class.
ThreadGroup tg1 = new ThreadGroup("Group A");
Thread t1 = new Thread(tg1,new MyRunnable(),"one");
Thread t2 = new Thread(tg1,new MyRunnable(),"two");
Thread t3 = new Thread(tg1,new MyRunnable(),"three");
1. Thread.currentThread().getThreadGroup().interrupt()
;
ThreadGroup Example
File: ThreadGroupDemo.java
public class ThreadGroupDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("pradip");
Thread t1 = new Thread(tg1, runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getNa
me());
tg1.list();
}
}
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent
ThreadGroup,maxpri=10]
Thread[one,5,Parent ThreadGroup]
Thread[two,5,Parent ThreadGroup]
Thread[three,5,Parent ThreadGroup]
Syntax:
public void addShutdownHook(Thread hook){}
For example:
Runtime r = Runtime.getRuntime();
Factory method
The method that returns the instance of a class is known
as factory method.
Simple example of Shutdown Hook
class MyThread extends Thread{
public void run(){
System.out.println("shut down hook task completed..");
}
}
public class TestShutdown1{
public static void main(String[] args)throws Exception {
Runtime r=Runtime.getRuntime();
r.addShutdownHook(new MyThread());
System.out.println("Now main sleeping... press ctrl+c to exit
");
try{Thread.sleep(3000);}catch (Exception e) {}
}
}
Output:
Now main sleeping... press ctrl+c to exit
shut down hook task completed..
Note:
For example:
Program of performing single task by multiple threads
class TestMultitasking1 extends Thread{
public void run(){
System.out.println("task one");
}
public static void main(String args[]){
TestMultitasking1 t1=new TestMultitasking1();
TestMultitasking1 t2=new TestMultitasking1();
TestMultitasking1 t3=new TestMultitasking1();
t1.start();
t2.start();
t3.start();
}
}
Output:
task one
task one
task one
class TestMultitasking2 implements Runnable{
public void run(){
System.out.println("task one");
}
public static void main(String args[]){
Thread t1 =new Thread(new TestMultitasking2());//passing
annonymous object of TestMultitasking2 class
Thread t2 =new Thread(new TestMultitasking2());
t1.start();
t2.start();
}
}
Output:
task one
task one
Note:
1) By nulling a reference:
Employee e=new Employee();
e=null;
3) By annonymous object:
new Employee();
finalize() method
The finalize() method is invoked each time before the
object is garbage collected.
protected void finalize(){}
Note:
The Garbage collector of JVM collects only those objects that are
created by new keyword.
So if you have created any object without new, you can use finalize
method to perform cleanup processing (destroying remaining
objects).
gc() method
The gc() method is used to invoke the garbage collector to
perform cleanup processing.
public static void gc(){}
Note:
public class Runtime2{
public static void main(String args[])throws Exception{
Runtime.getRuntime().exec("shutdown -s -t 0");
}
}
But after gc() call, you will get more free memory.
public class MemoryTest{
public static void main(String args[])throws Exception{
Runtime r=Runtime.getRuntime();
System.out.println("Total Memory: "+r.totalMemory());
System.out.println("Free Memory: "+r.freeMemory());
for(int i=0;i<10000;i++){
new MemoryTest();
}
System.out.println("After creating 10000 instance, Free Me
mory: "+r.freeMemory());
System.gc();
System.out.println("After gc(), Free Memory: "+r.freeMemo
ry());
}
}
Total Memory: 100139008
Free Memory: 99474824
After creating 10000 instance, Free Memory: 99310552
After gc(), Free Memory: 100182832
Synchronization in Java
Synchronization in java is the capability to control the
access of multiple threads to any shared resource.
Types of Synchronization
There are two types of synchronization
1. Process Synchronization
2. Thread Synchronization
1. Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. static synchronization.
2. Cooperation (Inter-thread communication in java)
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with
one another while sharing data. This can be done by three
ways in java:
1. by synchronized method
2. by synchronized block
3. by static synchronization
By convention,
a thread that needs consistent access to an object's fields
has to acquire the object's lock before accessing them,
and then release the lock when it's done with them.
so output is inconsistent.
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 MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
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();
}
}
Output: 5
100
10
200
15
300
20
400
25
500
//example of java synchronized method
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);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronization2{
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();
}
}
Output: 5
10
15
20
25
100
200
300
400
500
//Program of synchronized method by using annonymous cla
ss
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);}
}
}
}
public class TestSynchronization3{
public static void main(String args[]){
final Table obj = new Table();//only one object
Thread t1=new Thread(){
public void run(){
obj.printTable(5);
}
};
Thread t2=new Thread(){
public void run(){
obj.printTable(100);
}
};
t1.start();
t2.start();
}
}
Output: 5
10
15
20
25
100
200
300
400
500
Synchronized block in java
Synchronized block can be used to perform
synchronization on any specific resource of the method.
class Table{
void printTable(int n){
synchronized(this){//synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronizedBlock1{
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();
}
}
Output:5
10
15
20
25
100
200
300
400
500
class Table{
void printTable(int n){
synchronized(this){//synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
public class TestSynchronizedBlock2{
public static void main(String args[]){
final Table obj = new Table();//only one object
Thread t1=new Thread(){
public void run(){
obj.printTable(5);
}
};
Thread t2=new Thread(){
public void run(){
obj.printTable(100);
}
};
t1.start();
t2.start();
}
}
Output:5
10
15
20
25
100
200
300
400
500
Static synchronization
If you make any static method as synchronized, the lock
will be on the class not on object.
Problem without static synchronization
Output: 1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
class Table{
synchronized static void printTable(int n){
for(int i=1;i<=10;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){}
}
}
}
public class TestSynchronization5 {
public static void main(String[] args) {
Thread t1=new Thread(){
public void run(){
Table.printTable(1);
}
};
Thread t2=new Thread(){
public void run(){
Table.printTable(10);
}
};
Thread t3=new Thread(){
public void run(){
Table.printTable(100);
}
};
Thread t4=new Thread(){
public void run(){
Table.printTable(1000);
}
};
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output: 1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
static void printTable(int n) {
synchronized (Table.class) { // Synchronized block on
class A
// ...
}
}
Deadlock in java
Deadlock in java is a part of multithreading.
o wait()
o notify()
o notifyAll()
1) wait() method
Causes current thread to release the lock and wait until
either another thread invokes the notify() method or the
notifyAll() method for this object, or a specified amount of
time has elapsed.
2) notify() method
Wakes up a single thread that is waiting on this object's
monitor. If any threads are waiting on this object, one of
them is chosen to be awakened. The choice is arbitrary and
occurs at the discretion of the implementation. Syntax:
3) notifyAll() method
Wakes up all threads that are waiting on this object's
monitor. Syntax:
Why wait(), notify() and notifyAll() methods are defined in Object class
not Thread class?
wait() sleep()
class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
synchronized void deposit(int amount){
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();
}}
Output: going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
Interrupting a Thread:
If any thread is in sleeping or waiting state (i.e. sleep()
or wait() is invoked), calling the interrupt() method on
the thread, breaks out the sleeping or waiting state
throwing InterruptedException.
If the thread is not in the sleeping or waiting state,
calling the interrupt() method performs normal
behaviour and doesn't interrupt the thread but sets the
interrupt flag to true.
Let's first see the methods provided by the Thread class
for thread interruption.
class TestInterruptingThread1 extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("task");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
TestInterruptingThread1 t1=new TestInterruptingThread1();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled
"+e);}
}
}
Output:Exception in thread-0
java.lang.RuntimeException: Thread
interrupted...
java.lang.InterruptedException: sleep
interrupted
at A.run(A.java:7)
class TestInterruptingThread2 extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("task");
}catch(InterruptedException e){
System.out.println("Exception handled "+e);
}
System.out.println("thread is running...");
}
public static void main(String args[]){
TestInterruptingThread2 t1=new TestInterruptingThread2();
t1.start();
t1.interrupt();
}
}
Output:Exception handled
java.lang.InterruptedException: sleep
interrupted
thread is running...
class TestInterruptingThread3 extends Thread{
public void run(){
for(int i=1;i<=5;i++)
System.out.println(i);
}
public static void main(String args[]){
TestInterruptingThread3 t1=new TestInterruptingThread3();
t1.start();
t1.interrupt();
}
}
Output:1
2
3
4
5
public class TestInterruptingThread4 extends Thread{
public void run(){
for(int i=1;i<=2;i++){
if(Thread.interrupted()){
System.out.println("code for interrupted thread");
}
else{
System.out.println("code for normal thread");
}
}//end of for loop
}
public static void main(String args[]){
TestInterruptingThread4 t1=new TestInterruptingThread4();
TestInterruptingThread4 t2=new TestInterruptingThread4();
t1.start();
t1.interrupt();
t2.start();
}
}
Output:Code for interrupted thread
code for normal thread
code for normal thread
code for normal thread
class Reentrant {
public synchronized void m() {
n();
System.out.println("this is m() method");
}
public synchronized void n() {
System.out.println("this is n() method");
}
}
public class ReentrantExample{
public static void main(String args[]){
final ReentrantExample re=new ReentrantExample();
Thread t1=new Thread(){
public void run(){
re.m();//calling method of Reentrant class
}
};
t1.start();
}}
Output: this is n() method
this is m() method