Multi Threading
Multi Threading
Keep Watching
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use
multitasking to utilize the CPU. Multitasking can be achieved in two ways:
Threads are independent. If there occurs exception in one thread, it doesn't affect other
threads. It uses a shared memory area.
As shown in the above figure, a thread is executed inside the process. There is context-
switching between the threads. There can be multiple processes inside the OS, and one
process can have multiple threads.
1. New
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
Active: When a thread invokes the start() method, it moves from the new state to the
active state. The active state contains two states within it: one is runnable, and the other
is running.
o Runnable: A thread, that is ready to run is then moved to the runnable state. In the
runnable state, the thread may be running or may be ready to run at any given instant of
time. It is the duty of the thread scheduler to provide the thread time to run, i.e., moving
the thread the running state.
A program implementing multithreading acquires a fixed slice of time to each individual
thread. Each and every thread runs for a short span of time and when that allocated time
slice is over, the thread voluntarily gives up the CPU to the other thread, so that the
other threads can also run for their slice of time. Whenever such a scenario occurs, all
those threads that are willing to run, waiting for their turn to run, lie in the runnable
state. In the runnable state, there is a queue where the threads lie.
o Running: When the thread gets the CPU, it moves from the runnable to the running
state. Generally, the most common change in the state of a thread is from runnable to
running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently)
then, either the thread is in the blocked state or is in the waiting state.
For example, a thread (let's say its name is A) may want to print some data from the
printer. However, at the same time, the other thread (let's say its name is B) is using the
printer to print some data. Therefore, thread A has to wait for thread B to use the
printer. Thus, thread A is in the blocked state. A thread in the blocked state is unable to
perform any execution and thus never consume any cycle of the Central Processing Unit
(CPU). Hence, we can say that thread A remains idle until the thread scheduler
reactivates thread A, which is in the waiting or blocked state.
When the main thread invokes the join() method then, it is said that the main thread is
in the waiting state. The main thread then waits for the child threads to complete their
tasks. When the child threads complete their job, a notification is sent to the main
thread, which again moves the thread from waiting to the active state.
If there are a lot of threads in the waiting or blocked state, then it is the duty of the
thread scheduler to determine which thread to choose and which one to reject, and the
chosen thread is then given the opportunity to run.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its
name is A) has entered the critical section of a code and is not willing to leave that
critical section. In such a scenario, another thread (its name is B) has to wait forever,
which leads to starvation. To avoid such scenario, a timed waiting state is given to
thread B. Thus, thread lies in the waiting state for a specific span of time, and not
forever. A real example of timed waiting is when we invoke the sleep() method on a
specific thread. The sleep() method puts the thread in the timed wait state. After the
time runs out, the thread wakes up and start its execution from when it has left earlier.
Terminated: A thread reaches the termination state because of the following reasons:
o When a thread has finished its job, then it exists or terminates normally.
o Abnormal termination: It occurs when some unusual events such as an unhandled
exception or segmentation fault.
A terminated thread means the thread is no more in the system. In other words, the
thread is dead, and there is no way one can respawn (active after kill) the dead thread.
The following diagram shows the different states involved in the life cycle of a thread.
How to create a thread in Java
There are two ways to create a thread:
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.
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
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().
Starting a thread:
The start() method of Thread class is used to start a newly created thread. It performs
the following tasks:
System.out.println("thread is running...");
t1.start();
}
}Output:
thread is running...
Thread.sleep(500);
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
}
public static void main(String args[])
{
SleepDemo t1=new SleepDemo();
SleepDemo t2=new SleepDemo();
t1.start();
t2.start();
}
}
1)Thread class
import java.util.*;
import java.io.*;
class Slip2_1 extends Thread
{
String s1;
Slip2_1(String s)
{
s1=s;
start();
}
public void run()
{
System.out.println("Vowels are ");
for(int i=0;i<s1.length();i++)
{
try
{
char ch=s1.charAt(i);
if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||
ch=='u'||ch=='A'||ch=='E'||ch=='I'||ch=='O'||ch=='U')
System.out.println(" "+ch);
Thread.sleep(1500);
}
catch(InterruptedException e)
{
System.out.println(e);
}
}
}
public static void main(String a[]) throws Exception
{
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
System.out.println("Enter a string");
String str=br.readLine();
Slip2_1 v=new Slip2_1(str);
}
}
2)import java.io.BufferedReader;
import java.io.InputStreamReader;
}
Can we start a thread twice
No. After starting a thread, it can never be started again. If you does so,
an IllegalThreadStateException is thrown. In such case, thread will run once but for
second time, it will throw exception.
Syntax:
public void join()throws InterruptedException
As you can see in the above example,when t1 completes its task then t2 and t3 starts executing.
t2.start();
t3.start();
}
}
Output:1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the above example,when t1 is completes its task for 1500 miliseconds(3 times) then t2 and t3 starts
executing.
t1.setName("abcd");
System.out.println("After changing name of t1:"+t1.getName());
t2.setName("abcdefr");
System.out.println("After changing name of t1:"+t2.getName());
}
}
The currentThread() method:
The currentThread() method returns a reference to the currently executing thread
object.
Syntax:
public static Thread currentThread()
Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of
MAX_PRIORITY is 10.
}
public static void main(String args[]){
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:
running...
FileName: TestCallRun2.javay
Output:
1
2
3
4
1
2
3
4
As we can see in the above program that there is no context-switching because here t1
and t2 will be treated as normal object not thread object.
There are many java daemon threads running automatically e.g. gc, finalizer etc.
You can see all the detail by typing the console in the command prompt. The console
tool provides information about the loaded classes, memory usage, running threads etc.
26.6M
616
No Method Description
.
1) public void setDaemon(boolean is used to mark the current thread as daemon thread or
status) user thread.
Output:
File: MyThread.java
1. class TestDaemonThread2 extends Thread{
2. public void run(){
3. System.out.println("Name: "+Thread.currentThread().getName());
4. System.out.println("Daemon: "+Thread.currentThread().isDaemon());
5. }
6.
7. public static void main(String[] args){
8. TestDaemonThread2 t1=new TestDaemonThread2();
9. TestDaemonThread2 t2=new TestDaemonThread2();
10. t1.start();
11. t1.setDaemon(true);//will throw exception here
12. t2.start();
13. }
14. }
Test it Now
Output:
Synchronization in Java
Synchronization in Java is the capability to control the access of multiple threads to any
shared resource.
Java Synchronization is better option where we want to allow only one thread to access
the shared resource.
Types of Synchronization
There are two types of synchronization 27.1M
1. Process Synchronization
2. Thread Synchronization
Thread Synchronization
There are two types of thread synchronization mutual exclusive and inter-thread
communication.
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. It can be achieved by using the following three ways:
TestSynchronization1.java
class Table{
void printTable(int n){//method not synchronized
for(int i=1;i<=10;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
}
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
When a thread invokes a synchronized method, it automatically acquires the lock for
that object and releases it when the thread completes its task.
TestSynchronization2.java
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
Output:
5
10
15
20
25
100
200
300
400
500
TestSynchronization3.java
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
Suppose we have 50 lines of code in our method, but we want to synchronize only 5
lines, in such cases, we can use synchronized block.
If we put all the codes of the method in the synchronized block, it will work same as the
synchronized method.
Points to Remember
Syntax
TestSynchronizedBlock1.java
1. class Table
2. {
3. void printTable(int n){
4. synchronized(this){//synchronized block
5. for(int i=1;i<=5;i++){
6. System.out.println(n*i);
7. try{
8. Thread.sleep(400);
9. }catch(Exception e){System.out.println(e);}
10. }
11. }
12. }//end of the method
13. }
14.
15. class MyThread1 extends Thread{
16. Table t;
17. MyThread1(Table t){
18. this.t=t;
19. }
20. public void run(){
21. t.printTable(5);
22. }
23.
24. }
25. class MyThread2 extends Thread{
26. Table t;
27. MyThread2(Table t){
28. this.t=t;
29. }
30. public void run(){
31. t.printTable(100);
32. }
33. }
34.
35. public class TestSynchronizedBlock1{
36. public static void main(String args[]){
37. Table obj = new Table();//only one object
38. MyThread1 t1=new MyThread1(obj);
39. MyThread2 t2=new MyThread2(obj);
40. t1.start();
41. t2.start();
42. }
43. }
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.
TestSynchronization4.java
21.3M
452
1. class Table
2. {
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){}
9. }
10. }
11. }
12. class MyThread1 extends Thread{
13. public void run(){
14. Table.printTable(1);
15. }
16. }
17. class MyThread2 extends Thread{
18. public void run(){
19. Table.printTable(10);
20. }
21. }
22. class MyThread3 extends Thread{
23. public void run(){
24. Table.printTable(100);
25. }
26. }
27. class MyThread4 extends Thread{
28. public void run(){
29. Table.printTable(1000);
30. }
31. }
32. public class TestSynchronization4{
33. public static void main(String t[]){
34. MyThread1 t1=new MyThread1();
35. MyThread2 t2=new MyThread2();
36. MyThread3 t3=new MyThread3();
37. MyThread4 t4=new MyThread4();
38. t1.start();
39. t2.start();
40. t3.start();
41. t4.start();
42. }
43. }
Test it Now
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
o wait()
o notify()
o notifyAll()
1) wait() method
The 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.
The current thread must own this object's monitor, so it must be called from the
synchronized method only otherwise it will throw exception.
27.3M
475
Method Description
public final void wait(long timeout)throws It waits for the specified amount of
InterruptedException time.
2) notify() method
The 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:
The wait() method releases the lock. The sleep() method doesn't release the lock.
It should be notified by notify() or notifyAll() After the specified amount of time, sleep is
methods completed.
class Customer{
int amount=10000;
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...Ac balance is"+this.amount);
}
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();
}}
o/p
going to withdraw...15000
Less balance; waiting for deposit...
going to deposit...10000
deposit completed... 20000
withdraw completed...Ac balance is5000