Multithreading in Java
1. Multithreading
2. Multitasking
3. Process-based multitasking
4. Thread-based multitasking
5. What is Thread
Multithreading in Java is a process of executing multiple threads
simultaneously.
A thread is a lightweight sub-process, the smallest unit of processing.
Multiprocessing and multithreading, both are used to achieve multitasking.
However, we use multithreading than multiprocessing because threads use a
shared memory area. They don't allocate separate memory area so saves
memory, and context-switching between the threads takes less time than
process.
Java Multithreading is mostly used in games, animation, etc.
Advantages of Java Multithreading
1) It doesn't block the user because threads are independent and you can
perform multiple operations at the same time.
2) You can perform many operations together, so it saves time.
3) Threads are independent, so it doesn't affect other threads if an exception
occurs in a single thread.
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use
multitasking to utilize the CPU. Multitasking can be achieved in two ways:
o Process-based Multitasking (Multiprocessing)
o Thread-based Multitasking (Multithreading)
1) Process-based Multitasking (Multiprocessing)
o Each process has an address in memory. In other words, each process
allocates a separate memory area.
o A process is heavyweight.
o Cost of communication between the process is high.
o Switching from one process to another requires some time for saving
and loading registers, memory maps, updating lists, etc.
2) Thread-based Multitasking (Multithreading)
o Threads share the same address space.
o A thread is lightweight.
o Cost of communication between the thread is low.
Note: At least one process is required for each thread.
What is Thread in java
A thread is a lightweight subprocess, the smallest unit of processing. It is a
separate path of execution.
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.
Note: At a time one thread is executed only.
Java Thread class
Java provides Thread class to achieve thread programming. Thread class
provides constructors and methods to create and perform operations on a
thread. Thread class extends Object class and implements Runnable interface.
Java Thread Methods
S.N. Modifier Method Description
and Type
1) void start() It is used to start the execution of the
thread.
2) void run() It is used to do an action for a thread.
3) static void sleep() It sleeps a thread for the specified
amount of time.
4) static currentThread It returns a reference to the currently
Thread () executing thread object.
5) void join() It waits for a thread to die.
6) int getPriority() It returns the priority of the thread.
7) void setPriority() It changes the priority of the thread.
8) String getName() It returns the name of the thread.
9) void setName() It changes the name of the thread.
10) long getId() It returns the id of the thread.
11) boolean isAlive() It tests if the thread is alive.
12) static void yield() It causes the currently executing thread
object to pause and allow other threads
to execute temporarily.
13) void suspend() It is used to suspend the thread.
14) void resume() It is used to resume the suspended
thread.
15) void stop() It is used to stop the thread.
16) void destroy() It is used to destroy the thread group
and all of its subgroups.
17) boolean isDaemon() It tests if the thread is a daemon thread.
18) void setDaemon() It marks the thread as daemon or user
thread.
19) void interrupt() It interrupts the thread.
20) boolean isinterrupted() It tests whether the thread has been
interrupted.
21) static interrupted() It tests whether the current thread has
boolean been interrupted.
22) static int activeCount() It returns the number of active threads in
the current thread's thread group.
23) void checkAccess() It determines if the currently running
thread has permission to modify the
thread.
24) static holdLock() It returns true if and only if the current
boolean thread holds the monitor lock on the
specified object.
25) static void dumpStack() It is used to print a stack trace of the
current thread to the standard error
stream.
26) StackTraceE getStackTrace It returns an array of stack trace elements
lement[] () representing the stack dump of the
thread.
27) static int enumerate() It is used to copy every active thread's
thread group and its subgroup into the
specified array.
28) [Link] getState() It is used to return the state of the
e thread.
29) ThreadGrou getThreadGro It is used to return the thread group to
p up() which this thread belongs
30) String toString() It is used to return a string representation
of this thread, including the thread's
name, priority, and thread group.
31) void notify() It is used to give the notification for only
one thread which is waiting for a
particular object.
32) void notifyAll() It is used to give the notification to all
waiting threads of a particular object.
33) void setContextCla It sets the context ClassLoader for the
ssLoader() Thread.
34) ClassLoader getContextCla It returns the context ClassLoader for the
ssLoader() thread.
35) static getDefaultUn It returns the default handler invoked
[Link] caughtExcepti when a thread abruptly terminates due to
aughtExcep onHandler() an uncaught exception.
tionHandler
36) static void setDefaultUnc It sets the default handler invoked when
aughtExceptio a thread abruptly terminates due to an
nHandler() uncaught exception.
Life cycle of a Thread (Thread
States)
In Java, a thread always exists in any one of the following states. These states
are:
1. New
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
Explanation of Different Thread States
New: Whenever a new thread is created, it is always in the new state. For a
thread in the new state, the code has not been run yet and thus has not begun
its execution.
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.
Implementation of Thread States
In Java, one can get the current state of a thread using
the [Link]() method. The [Link] class of Java
provides the constants ENUM to represent the state of a thread. These
constants are:
1. public static final [Link] NEW
It represents the first state of a thread that is the NEW state.
1. public static final [Link] RUNNABLE
It represents the runnable [Link] means a thread is waiting in the queue to
run.
1. public static final [Link] BLOCKED
It represents the blocked state. In this state, the thread is waiting to acquire a
lock.
1. public static final [Link] WAITING
It represents the waiting state. A thread will go to this state when it invokes
the [Link]() method, or [Link]() method with no timeout. A thread in
the waiting state is waiting for another thread to complete its task.
1. public static final [Link] TIMED_WAITING
It represents the timed waiting state. The main difference between waiting and
timed waiting is the time constraint. Waiting has no time constraint, whereas
timed waiting has the time constraint. A thread invoking the following method
reaches the timed waiting state.
o sleep
o join with timeout
o wait with timeout
o parkUntil
o parkNanos
1. public static final [Link] TERMINATED
It represents the final state of a thread that is terminated or dead. A
terminated thread means it has completed its execution.
Java Program for Demonstrating Thread
States
The following Java program shows some of the states of a thread defined
above.
FileName: [Link]
1. // ABC class implements the interface Runnable
2. class ABC implements Runnable
3. {
4. public void run()
5. {
6.
7. // try-catch block
8. try
9. {
10.// moving thread t2 to the state timed waiting
[Link](100);
12.}
[Link] (InterruptedException ie)
14.{
[Link]();
16.}
17.
18.
[Link]("The state of thread t1 while it invoked the method join() o
n thread t2 -"+ [Link]());
20.
21.// try-catch block
[Link]
23.{
[Link](200);
25.}
[Link] (InterruptedException ie)
27.{
[Link]();
29.}
30.}
31.}
32.
33.// ThreadState class implements the interface Runnable
[Link] class ThreadState implements Runnable
35.{
[Link] static Thread t1;
[Link] static ThreadState obj;
38.
39.// main method
[Link] static void main(String argvs[])
41.{
42.// creating an object of the class ThreadState
[Link] = new ThreadState();
44.t1 = new Thread(obj);
45.
46.// thread t1 is spawned
47.// The thread t1 is currently in the NEW state.
[Link]("The state of thread t1 after spawning it - " + [Link]());
49.
50.// invoking the start() method on
51.// the thread t1
[Link]();
53.
54.// thread t1 is moved to the Runnable state
[Link]("The state of thread t1 after invoking the method start() on
it - " + [Link]());
56.}
57.
[Link] void run()
59.{
[Link] myObj = new ABC();
[Link] t2 = new Thread(myObj);
62.
63.// thread t2 is created and is currently in the NEW state.
[Link]("The state of thread t2 after spawning it - "+ [Link]());
[Link]();
66.
67.// thread t2 is moved to the runnable state
[Link]("the state of thread t2 after calling the method start() on it -
" + [Link]());
69.
70.// try-catch block for the smooth flow of the program
[Link]
72.{
73.// moving the thread t1 to the state timed waiting
[Link](200);
75.}
[Link] (InterruptedException ie)
77.{
[Link]();
79.}
80.
[Link]("The state of thread t2 after invoking the method sleep() on
it - "+ [Link]() );
82.
83.// try-catch block for the smooth flow of the program
[Link]
85.{
86.// waiting for thread t2 to complete its execution
[Link]();
88.}
[Link] (InterruptedException ie)
90.{
[Link]();
92.}
[Link]("The state of thread t2 when it has completed it's execution
- " + [Link]());
94.}
95.
96.}
Output:
The state of thread t1 after spawning it - NEW
The state of thread t1 after invoking the method start() on it - RUNNABLE
The state of thread t2 after spawning it - NEW
the state of thread t2 after calling the method start() on it - RUNNABLE
The state of thread t1 while it invoked the method join() on thread t2 -
TIMED_WAITING
The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING
The state of thread t2 when it has completed it's execution - TERMINATED
Explanation: Whenever we spawn a new thread, that thread attains the new
state. When the method start() is invoked on a thread, the thread scheduler
moves that thread to the runnable state. Whenever the join() method is
invoked on any thread instance, the current thread executing that statement
has to wait for this thread to finish its execution, i.e., move that thread to the
terminated state. Therefore, before the final print statement is printed on the
console, the program invokes the method join() on thread t2, making the
thread t1 wait while the thread t2 finishes its execution and thus, the thread t2
get to the terminated or dead state. Thread t1 goes to the waiting state
because it is waiting for thread t2 to finish it's execution as it has invoked the
method join() on thread t2.
Java Threads | How to create a
thread in Java
There are two ways to create a thread:
1. By extending Thread class
2. By implementing Runnable interface.
Thread class:
Thread class provide constructors and methods to create and perform
operations on a [Link] class extends Object class and implements
Runnable interface.
Commonly used Constructors of Thread class:
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
Commonly used methods of Thread class:
1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the [Link] calls the run()
method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing
thread to sleep (temporarily cease execution) for the specified number
of milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the
specified miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
[Link] Thread currentThread(): returns the reference of currently
executing thread.
[Link] int getId(): returns the id of the thread.
[Link] [Link] getState(): returns the state of the thread.
[Link] boolean isAlive(): tests if the thread is alive.
[Link] void yield(): causes the currently executing thread object to
temporarily pause and allow other threads to execute.
[Link] void suspend(): is used to suspend the thread(depricated).
[Link] void resume(): is used to resume the suspended
thread(depricated).
[Link] void stop(): is used to stop the thread(depricated).
[Link] boolean isDaemon(): tests if the thread is a daemon thread.
[Link] void setDaemon(boolean b): marks the thread as daemon or
user thread.
[Link] void interrupt(): interrupts the thread.
[Link] boolean isInterrupted(): tests if the thread has been
interrupted.
[Link] static boolean interrupted(): tests if the current thread has
been interrupted.
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(): is used to perform action for a thread.
Starting a thread:
The start() method of Thread class is used to start a newly created thread. It
performs the 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
FileName: [Link]
1. class Multi extends Thread{
2. public void run(){
3. [Link]("thread is running...");
4. }
5. public static void main(String args[]){
6. Multi t1=new Multi();
7. [Link]();
8. }
9. }
Output:
thread is running...
2) Java Thread Example by implementing
Runnable interface
FileName: [Link]
1. class Multi3 implements Runnable{
2. public void run(){
3. [Link]("thread is running...");
4. }
5.
6. public static void main(String args[]){
7. Multi3 m1=new Multi3();
8. Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
9. [Link]();
10. }
11.}
Output:
thread is running...
If you are not extending the Thread class, your class object would not be
treated as a thread object. So you need to explicitly create the Thread class
object. We are passing the object of your class that implements Runnable so
that your class run() method may execute.
3) Using the Thread Class: Thread(String Name)
We can directly use the Thread class to spawn new threads using the
constructors defined above.
FileName: [Link]
1. public class MyThread1
2. {
3. // Main method
4. public static void main(String argvs[])
5. {
6. // creating an object of the Thread class using the constructor Thread(String n
ame)
7. Thread t= new Thread("My first thread");
8.
9. // the start() method moves the thread to the active state
[Link]();
11.// getting the thread name by invoking the getName() method
[Link] str = [Link]();
[Link](str);
14.}
15.}
Output:
My first thread
4) Using the Thread Class: Thread(Runnable r,
String name)
Observe the following program.
FileName: [Link]
1. public class MyThread2 implements Runnable
2. {
3. public void run()
4. {
5. [Link]("Now the thread is running ...");
6. }
7.
8. // main method
9. public static void main(String argvs[])
10.{
11.// creating an object of the class MyThread2
[Link] r1 = new MyThread2();
13.
14.// creating an object of the class Thread using Thread(Runnable r, String name
)
[Link] th1 = new Thread(r1, "My new thread");
16.
17.// the start() method moves the thread to the active state
[Link]();
19.
20.// getting the thread name by invoking the getName() method
[Link] str = [Link]();
[Link](str);
23.}
24.}
Output:
My new thread
Now the thread is running ...
Thread Scheduler in Java
A component of Java that decides which thread to run or execute and which
thread to wait is called a thread scheduler in Java. In Java, a thread is only
chosen by a thread scheduler if it is in the runnable state. However, if there is
more than one thread in the runnable state, it is up to the thread scheduler to
pick one of the threads and ignore the other ones. There are some criteria that
decide which thread will execute first. There are two factors for scheduling a
thread i.e. Priority and Time of arrival.
Priority: Priority of each thread lies between 1 to 10. If a thread has a higher
priority, it means that thread has got a better chance of getting picked up by
the thread scheduler.
Time of Arrival: Suppose two threads of the same priority enter the runnable
state, then priority cannot be the factor to pick a thread from these two
threads. In such a case, arrival time of thread is considered by the thread
scheduler. A thread that arrived first gets the preference over the other
threads.
Thread Scheduler Algorithms
On the basis of the above-mentioned factors, the scheduling algorithm is
followed by a Java thread scheduler.
First Come First Serve Scheduling:
In this scheduling algorithm, the scheduler picks the threads thar arrive first in
the runnable queue. Observe the following table:
Threads Time of Arrival
t1 0
t2 1
t3 2
t4 3
In the above table, we can see that Thread t1 has arrived first, then Thread t2,
then t3, and at last t4, and the order in which the threads will be processed is
according to the time of arrival of threads.
Hence, Thread t1 will be processed first, and Thread t4 will be processed last.
Time-slicing scheduling:
Usually, the First Come First Serve algorithm is non-preemptive, which is bad
as it may lead to infinite blocking (also known as starvation). To avoid that,
some time-slices are provided to the threads so that after some time, the
running thread has to give up the CPU. Thus, the other waiting threads also
get time to run their job.
In the above diagram, each thread is given a time slice of 2 seconds. Thus,
after 2 seconds, the first thread leaves the CPU, and the CPU is then captured
by Thread2. The same process repeats for the other threads too.
Preemptive-Priority Scheduling:
The name of the scheduling algorithm denotes that the algorithm is related to
the priority of the threads.
Suppose there are multiple threads available in the runnable state. The thread
scheduler picks that thread that has the highest priority. Since the algorithm is
also preemptive, therefore, time slices are also provided to the threads to
avoid starvation. Thus, after some time, even if the highest priority thread has
not completed its job, it has to release the CPU because of preemption.
Working of the Java Thread Scheduler
Let's understand the working of the Java thread scheduler. Suppose, there are
five threads that have different arrival times and different priorities. Now, it is
the responsibility of the thread scheduler to decide which thread will get the
CPU first.
The thread scheduler selects the thread that has the highest priority, and the
thread begins the execution of the job. If a thread is already in runnable state
and another thread (that has higher priority) reaches in the runnable state,
then the current thread is pre-empted from the processor, and the arrived
thread with higher priority gets the CPU time.
When two threads (Thread 2 and Thread 3) having the same priorities and
arrival time, the scheduling will be decided on the basis of FCFS algorithm.
Thus, the thread that arrives first gets the opportunity to execute first.
[Link]() in Java with
Examples
The Java Thread class provides the two variant of the sleep() method. First one
accepts only an arguments, whereas the other variant accepts two arguments.
The method sleep() is being used to halt the working of a thread for a given
amount of time. The time up to which the thread remains in the sleeping state
is known as the sleeping time of the thread. After the sleeping time is over, the
thread starts its execution from where it has left.
The sleep() Method Syntax:
Following are the syntax of the sleep() method.
1. public static void sleep(long mls) throws InterruptedException
2. public static void sleep(long mls, int n) throws InterruptedException
The method sleep() with the one parameter is the native method, and the
implementation of the native method is accomplished in another
programming language. The other methods having the two parameters are
not the native method. That is, its implementation is accomplished in Java. We
can access the sleep() methods with the help of the Thread class, as the
signature of the sleep() methods contain the static keyword. The native, as well
as the non-native method, throw a checked Exception. Therefore, either try-
catch block or the throws keyword can work here.
The [Link]() method can be used with any thread. It means any other
thread or the main thread can invoke the sleep() method.
Parameters:
The following are the parameters used in the sleep() method.
mls: The time in milliseconds is represented by the parameter mls. The
duration for which the thread will sleep is given by the method sleep().
n: It shows the additional time up to which the programmer or developer
wants the thread to be in the sleeping state. The range of n is from 0 to
999999.
The method does not return anything.
Important Points to Remember About the Sleep()
Method
Whenever the [Link]() methods execute, it always halts the execution of
the current thread.
Whenever another thread does interruption while the current thread is already
in the sleep mode, then the InterruptedException is thrown.
If the system that is executing the threads is busy, then the actual sleeping
time of the thread is generally more as compared to the time passed in
arguments. However, if the system executing the sleep() method has less load,
then the actual sleeping time of the thread is almost equal to the time passed
in the argument.
Example of the sleep() method in Java : on the
custom thread
The following example shows how one can use the sleep() method on the
custom thread.
FileName: [Link]
1. class TestSleepMethod1 extends Thread{
2. public void run(){
3. for(int i=1;i<5;i++){
4. // the thread will sleep for the 500 milli seconds
5. try{[Link](500);}catch(InterruptedException e){[Link](e);}
6. [Link](i);
7. }
8. }
9. public static void main(String args[]){
10. TestSleepMethod1 t1=new TestSleepMethod1();
11. TestSleepMethod1 t2=new TestSleepMethod1();
12.
13. [Link]();
14. [Link]();
15. }
16.}
Output:
1
1
2
2
3
3
4
4
As you know well that at a time only one thread is executed. If you sleep a
thread for the specified time, the thread scheduler picks up another thread
and so on.
Example of the sleep() Method in Java : on the
main thread
FileName: [Link]
1. // important import statements
2. import [Link];
3. import [Link].*;
4.
5.
6. public class TestSleepMethod2
7. {
8. // main method
9. public static void main(String argvs[])
10.{
11.
[Link] {
[Link] (int j = 0; j < 5; j++)
14.{
15.
16.// The main thread sleeps for the 1000 milliseconds, which is 1 sec
17.// whenever the loop runs
[Link](1000);
19.
20.// displaying the value of the variable
[Link](j);
22.}
23.}
[Link] (Exception expn)
25.{
26.// catching the exception
[Link](expn);
28.}
29.}
30.}
Output:
0
1
2
3
4
Example of the sleep() Method in Java: When the
sleeping time is -ive
The following example throws the exception IllegalArguementException when
the time for sleeping is negative.
FileName: [Link]
1. // important import statements
2. import [Link];
3. import [Link].*;
4.
5. public class TestSleepMethod3
6. {
7. // main method
8. public static void main(String argvs[])
9. {
10.// we can also use throws keyword followed by
11.// exception name for throwing the exception
[Link]
13.{
[Link] (int j = 0; j < 5; j++)
15.{
16.
17.// it throws the exception IllegalArgumentException
18.// as the time is -ive which is -100
[Link](-100);
20.
21.// displaying the variable's value
[Link](j);
23.}
24.}
[Link] (Exception expn)
26.{
27.
28.// the exception iscaught here
[Link](expn);
30.}
31.}
32.}
Output:
[Link]: timeout value is negative
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.
Let's understand it by the example given below:
1. public class TestThreadTwice1 extends Thread{
2. public void run(){
3. [Link]("running...");
4. }
5. public static void main(String args[]){
6. TestThreadTwice1 t1=new TestThreadTwice1();
7. [Link]();
8. [Link]();
9. }
10.}
Test it Now
Output:
running
Exception in thread "main" [Link]
What if we call Java run() method
directly instead start() method?
o Each thread starts in a separate call stack.
o Invoking the run() method from the main thread, the run() method goes
onto the current call stack rather than at the beginning of a new call
stack.
FileName: [Link]
1. class TestCallRun1 extends Thread{
2. public void run(){
3. [Link]("running...");
4. }
5. public static void main(String args[]){
6. TestCallRun1 t1=new TestCallRun1();
7. [Link]();//fine, but does not start a separate call stack
8. }
9. }
Test it Now
Output:
running...
Problem if you direct call run() method
FileName: [Link]
1. class TestCallRun2 extends Thread{
2. public void run(){
3. for(int i=1;i<5;i++){
4. try{[Link](500);}catch(InterruptedException e){[Link](e);}
5. [Link](i);
6. }
7. }
8. public static void main(String args[]){
9. TestCallRun2 t1=new TestCallRun2();
10. TestCallRun2 t2=new TestCallRun2();
11.
12. [Link]();
13. [Link]();
14. }
15.}
Test it Now
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.
Java join() method
The join() method in Java is provided by the [Link] class that permits
one thread to wait until the other thread to finish its execution. Suppose th be
the object the class Thread whose thread is doing its execution currently, then
the [Link](); statement ensures that th is finished before the program does the
execution of the next statement. When there are more than one thread
invoking the join() method, then it leads to overloading on the join() method
that permits the developer or programmer to mention the waiting period.
However, similar to the sleep() method in Java, the join() method is also
dependent on the operating system for the timing, so we should not assume
that the join() method waits equal to the time we mention in the parameters.
The following are the three overloaded join() methods.
Description of The Overloaded join()
Method
join(): When the join() method is invoked, the current thread stops its
execution and the thread goes into 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:
1. public final void join() throws InterruptedException
join(long mls): When the join() method is invoked, the current thread stops
its execution and the thread goes into the wait state. The current thread
remains in the wait state until the thread on which the join() method is
invoked called is dead or the wait for the specified time frame(in milliseconds)
is over.
Syntax:
1. public final synchronized void join(long mls) throws InterruptedException,
where mls is in milliseconds
join(long mls, int nanos): When the join() method is invoked, the current
thread stops its execution and go into the wait state. The current thread
remains in the wait state until the thread on which the join() method is
invoked called is dead or the wait for the specified time frame(in milliseconds
+ nanos) is over.
Syntax:
1. public final synchronized void join(long mls, int nanos) throws InterruptedE
xception, where mls is in milliseconds.
Example of join() Method in Java
The following program shows the usage of the join() method.
FileName: [Link]
1. // A Java program for understanding
2. // the joining of threads
3.
4. // import statement
5. import [Link].*;
6.
7. // The ThreadJoin class is the child class of the class Thread
8. class ThreadJoin extends Thread
9. {
10.// overriding the run method
[Link] void run()
12.{
[Link] (int j = 0; j < 2; j++)
14.{
[Link]
16.{
17.// sleeping the thread for 300 milli seconds
[Link](300);
[Link]("The current thread name is: " + [Link]().get
Name());
20.}
21.// catch block for catching the raised exception
[Link](Exception e)
23.{
[Link]("The exception has been caught: " + e);
25.}
[Link]( j );
27.}
28.}
29.}
30.
[Link] class ThreadJoinExample
32.{
33.// main method
[Link] static void main (String argvs[])
35.{
36.
37.// creating 3 threads
[Link] th1 = new ThreadJoin();
[Link] th2 = new ThreadJoin();
[Link] th3 = new ThreadJoin();
41.
42.// thread th1 starts
[Link]();
44.
45.// starting the second thread after when
46.// the first thread th1 has ended or died.
[Link]
48.{
[Link]("The current thread name is: "+ [Link]().get
Name());
50.
51.// invoking the join() method
[Link]();
53.}
54.
55.// catch block for catching the raised exception
[Link](Exception e)
57.{
[Link]("The exception has been caught " + e);
59.}
60.
61.// thread th2 starts
[Link]();
63.
64.// starting the th3 thread after when the thread th2 has ended or died.
[Link]
66.{
[Link]("The current thread name is: " + [Link]().get
Name());
[Link]();
69.}
70.
71.// catch block for catching the raised exception
[Link](Exception e)
73.{
[Link]("The exception has been caught " + e);
75.}
76.
77.// thread th3 starts
[Link]();
79.}
80.}
Output:
The current thread name is: main
The current thread name is: Thread - 0
0
The current thread name is: Thread - 0
1
The current thread name is: main
The current thread name is: Thread - 1
0
The current thread name is: Thread - 1
1
The current thread name is: Thread - 2
0
The current thread name is: Thread - 2
1
Explanation: The above program shows that the second thread th2 begins
after the first thread th1 has ended, and the thread th3 starts its work after the
second thread th2 has ended or died.
The Join() Method: InterruptedException
We have learnt in the description of the join() method that whenever the
interruption of the thread occurs, it leads to the throwing of
InterruptedException. The following example shows the same.
FileName: [Link]
1. class ABC extends Thread
2. {
3. Thread threadToInterrupt;
4. // overriding the run() method
5. public void run()
6. {
7. // invoking the method interrupt
8. [Link]();
9. }
10.}
11.
12.
[Link] class ThreadJoinExample1
14.{
15.// main method
[Link] static void main(String[] argvs)
17.{
[Link]
19.{
20.// creating an object of the class ABC
[Link] th1 = new ABC();
22.
[Link] = [Link]();
[Link]();
25.
26.// invoking the join() method leads
27.// to the generation of InterruptedException
[Link]();
29.}
[Link] (InterruptedException ex)
31.{
[Link]("The exception has been caught. " + ex);
33.}
34.}
35.}
Output:
The exception has been caught. [Link]
Some More Examples of the join()
Method
Let' see some other examples.
Filename: [Link]
1. class TestJoinMethod1 extends Thread{
2. public void run(){
3. for(int i=1;i<=5;i++){
4. try{
5. [Link](500);
6. }catch(Exception e){[Link](e);}
7. [Link](i);
8. }
9. }
[Link] static void main(String args[]){
11. TestJoinMethod1 t1=new TestJoinMethod1();
12. TestJoinMethod1 t2=new TestJoinMethod1();
13. TestJoinMethod1 t3=new TestJoinMethod1();
14. [Link]();
15. try{
16. [Link]();
17. }catch(Exception e){[Link](e);}
18.
19. [Link]();
20. [Link]();
21. }
22.}
Output:
1
2
3
4
5
1
1
2
2
3
3
4
4
5
5
We can see in the above example, when t1 completes its task then t2 and t3
starts executing.
join(long miliseconds) Method Example
Filename: [Link]
1. class TestJoinMethod2 extends Thread{
2. public void run(){
3. for(int i=1;i<=5;i++){
4. try{
5. [Link](500);
6. }catch(Exception e){[Link](e);}
7. [Link](i);
8. }
9. }
[Link] static void main(String args[]){
11. TestJoinMethod2 t1=new TestJoinMethod2();
12. TestJoinMethod2 t2=new TestJoinMethod2();
13. TestJoinMethod2 t3=new TestJoinMethod2();
14. [Link]();
15. try{
16. [Link](1500);
17. }catch(Exception e){[Link](e);}
18.
19. [Link]();
20. [Link]();
21. }
22.}
Output:
1
2
3
1
4
1
2
5
2
3
3
4
4
5
5
In the above example, when t1 completes its task for 1500 milliseconds(3
times), then t2 and t3 start executing.
Naming Thread and Current
Thread
Naming Thread
The Thread class provides methods to change and get the name of a thread.
By default, each thread has a name, i.e. thread-0, thread-1 and so on. By we
can change the name of the thread by using the setName() method. The
syntax of setName() and getName() methods are given below:
1. public String getName(): is used to return the name of a thread.
2. public void setName(String name): is used to change the name of a thread.
We can also set the name of a thread directly when we create a new thread
using the constructor of the class.
Example of naming a thread : Using setName()
Method
FileName: [Link]
1. class TestMultiNaming1 extends Thread{
2. public void run(){
3. [Link]("running...");
4. }
5. public static void main(String args[]){
6. TestMultiNaming1 t1=new TestMultiNaming1();
7. TestMultiNaming1 t2=new TestMultiNaming1();
8. [Link]("Name of t1:"+[Link]());
9. [Link]("Name of t2:"+[Link]());
10.
11. [Link]();
12. [Link]();
13.
14. [Link]("Sonoo Jaiswal");
15. [Link]("After changing name of t1:"+[Link]());
16. }
17.}
Test it Now
Output:
Name of t1:Thread-0
Name of t2:Thread-1
After changing name of t1:Sonoo Jaiswal
running...
running...
Example of naming a thread : Without Using
setName() Method
One can also set the name of a thread at the time of the creation of a thread,
without using the setName() method. Observe the following code.
FileName: [Link]
1. // A Java program that shows how one can
2. // set the name of a thread at the time
3. // of creation of the thread
4.
5. // import statement
6. import [Link].*;
7.
8. // The ThreadNameClass is the child class of the class Thread
9. class ThreadName extends Thread
10.{
11.
12.// constructor of the class
[Link](String threadName)
14.{
15.// invoking the constructor of
16.// the superclass, which is Thread class.
[Link](threadName);
18.}
19.
20.// overriding the method run()
[Link] void run()
22.{
[Link](" The thread is executing....");
24.}
25.}
26.
[Link] class ThreadNamingExample
28.{
29.// main method
[Link] static void main (String argvs[])
31.{
32.// creating two threads and settting their name
33.// using the contructor of the class
[Link] th1 = new ThreadName("JavaTpoint1");
[Link] th2 = new ThreadName("JavaTpoint2");
36.
37.// invoking the getName() method to get the names
38.// of the thread created above
[Link]("Thread - 1: " + [Link]());
[Link]("Thread - 2: " + [Link]());
41.
42.
43.// invoking the start() method on both the threads
[Link]();
[Link]();
46.}
47.}
Output:
Thread - 1: JavaTpoint1
Thread - 2: JavaTpoint2
The thread is executing....
The thread is executing....
Current Thread
The currentThread() method returns a reference of the currently executing
thread.
1. public static Thread currentThread()
Example of currentThread() method
FileName: [Link]
1. class TestMultiNaming2 extends Thread{
2. public void run(){
3. [Link]([Link]().getName());
4. }
5. public static void main(String args[]){
6. TestMultiNaming2 t1=new TestMultiNaming2();
7. TestMultiNaming2 t2=new TestMultiNaming2();
8.
9. [Link]();
10. [Link]();
11. }
12.}
Test it Now
Output:
Thread-0
Thread-1
Priority of a Thread (Thread
Priority)
Each thread has a priority. Priorities are represented by a number between 1
and 10. In most cases, the thread scheduler schedules the threads according
to their priority (known as preemptive scheduling). But it is not guaranteed
because it depends on JVM specification that which scheduling it chooses.
Note that not only JVM a Java programmer can also assign the priorities of a
thread explicitly in a Java program.
Setter & Getter Method of Thread
Priority
Let's discuss the setter and getter method of the thread priority.
public final int getPriority(): The [Link]() method
returns the priority of the given thread.
public final void setPriority(int newPriority): The
[Link]() method updates or assign the priority of the
thread to newPriority. The method throws IllegalArgumentException if the
value newPriority goes out of the range, which is 1 (minimum) to 10
(maximum).
3 constants defined in Thread class:
1. public static int MIN_PRIORITY
2. public static int NORM_PRIORITY
3. public static int MAX_PRIORITY
Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY
is 1 and the value of MAX_PRIORITY is 10.
Example of priority of a Thread:
FileName: [Link]
1. // Importing the required classes
2. import [Link].*;
3.
4. public class ThreadPriorityExample extends Thread
5. {
6.
7. // Method 1
8. // Whenever the start() method is called by a thread
9. // the run() method is invoked
[Link] void run()
11.{
12.// the print statement
[Link]("Inside the run() method");
14.}
15.
16.// the main method
[Link] static void main(String argvs[])
18.{
19.// Creating threads with the help of ThreadPriorityExample class
[Link] th1 = new ThreadPriorityExample();
[Link] th2 = new ThreadPriorityExample();
[Link] th3 = new ThreadPriorityExample();
23.
24.// We did not mention the priority of the thread.
25.// Therefore, the priorities of the thread is 5, the default value
26.
27.// 1st Thread
28.// Displaying the priority of the thread
29.// using the getPriority() method
[Link]("Priority of the thread th1 is : " + [Link]());
31.
32.// 2nd Thread
33.// Display the priority of the thread
[Link]("Priority of the thread th2 is : " + [Link]());
35.
36.// 3rd Thread
37.// // Display the priority of the thread
[Link]("Priority of the thread th2 is : " + [Link]());
39.
40.// Setting priorities of above threads by
41.// passing integer arguments
[Link](6);
[Link](3);
[Link](9);
45.
46.// 6
[Link]("Priority of the thread th1 is : " + [Link]());
48.
49.// 3
[Link]("Priority of the thread th2 is : " + [Link]());
51.
52.// 9
[Link]("Priority of the thread th3 is : " + [Link]());
54.
55.// Main thread
56.
57.// Displaying name of the currently executing thread
[Link]("Currently Executing The Thread : " + [Link](
).getName());
59.
[Link]("Priority of the main thread is : " + [Link]().g
etPriority());
61.
62.// Priority of the main thread is 10 now
[Link]().setPriority(10);
64.
[Link]("Priority of the main thread is : " + [Link]().g
etPriority());
66.}
67.}
Output:
Priority of the thread th1 is : 5
Priority of the thread th2 is : 5
Priority of the thread th2 is : 5
Priority of the thread th1 is : 6
Priority of the thread th2 is : 3
Priority of the thread th3 is : 9
Currently Executing The Thread : main
Priority of the main thread is : 5
Priority of the main thread is : 10
We know that a thread with high priority will get preference over lower
priority threads when it comes to the execution of threads. However, there can
be other scenarios where two threads can have the same priority. All of the
processing, in order to look after the threads, is done by the Java thread
scheduler. Refer to the following example to comprehend what will happen if
two threads have the same priority.
FileName: [Link]
1. // importing the [Link] package
2. import [Link].*;
3.
4. public class ThreadPriorityExample1 extends Thread
5. {
6.
7. // Method 1
8. // Whenever the start() method is called by a thread
9. // the run() method is invoked
[Link] void run()
11.{
12.// the print statement
[Link]("Inside the run() method");
14.}
15.
16.
17.// the main method
[Link] static void main(String argvs[])
19.{
20.
21.// Now, priority of the main thread is set to 7
[Link]().setPriority(7);
23.
24.// the current thread is retrieved
25.// using the currentThread() method
26.
27.// displaying the main thread priority
28.// using the getPriority() method of the Thread class
[Link]("Priority of the main thread is : " + [Link]().g
etPriority());
30.
31.// creating a thread by creating an object of the class ThreadPriorityExample1
32.ThreadPriorityExample1 th1 = new ThreadPriorityExample1();
33.
34.// th1 thread is the child of the main thread
35.// therefore, the th1 thread also gets the priority 7
36.
37.// Displaying the priority of the current thread
[Link]("Priority of the thread th1 is : " + [Link]());
39.}
40.}
Output:
Priority of the main thread is : 7
Priority of the thread th1 is : 7
Explanation: If there are two threads that have the same priority, then one
can not predict which thread will get the chance to execute first. The execution
then is dependent on the thread scheduler's algorithm (First Come First Serve,
Round-Robin, etc.)
Example of IllegalArgumentException
We know that if the value of the parameter newPriority of the method
getPriority() goes out of the range (1 to 10), then we get the
IllegalArgumentException. Let's observe the same with the help of an example.
FileName: [Link]
1. // importing the [Link] package
2. import [Link].*;
3.
4. public class IllegalArgumentException extends Thread
5. {
6.
7. // the main method
8. public static void main(String argvs[])
9. {
10.
11.// Now, priority of the main thread is set to 17, which is greater than 10
[Link]().setPriority(17);
13.
14.// The current thread is retrieved
15.// using the currentThread() method
16.
17.// displaying the main thread priority
18.// using the getPriority() method of the Thread class
[Link]("Priority of the main thread is : " + [Link]().g
etPriority());
20.
21.}
22.}
When we execute the above program, we get the following exception:
Exception in thread "main" [Link]
at [Link]/[Link]([Link])
at [Link]([Link])
Daemon Thread in Java
Daemon thread in Java is a service provider thread that provides services to the
user thread. Its life depend on the mercy of user threads i.e. when all the user
threads dies, JVM terminates this thread automatically.
There are many java daemon threads running automatically e.g. gc, finalizer
etc.
You can see all the detail by typing the jconsole in the command prompt. The
jconsole tool provides information about the loaded classes, memory usage,
running threads etc.
Points to remember for Daemon Thread
in Java
o It provides services to user threads for background supporting tasks. It
has no role in life than to serve user threads.
o Its life depends on user threads.
o It is a low priority thread.
Why JVM terminates the daemon thread if there
is no user thread?
The sole purpose of the daemon thread is that it provides services to user
thread for background supporting task. If there is no user thread, why should
JVM keep running this thread. That is why JVM terminates the daemon thread
if there is no user thread.
Methods for Java Daemon thread by Thread
class
The [Link] class provides two methods for java daemon thread.
No Method Description
.
1) public void setDaemon(boolean is used to mark the current thread as daemon
status) user thread.
2) public boolean isDaemon() is used to check that current is daemon.
Simple example of Daemon thread in java
File: [Link]
1. public class TestDaemonThread1 extends Thread{
2. public void run(){
3. if([Link]().isDaemon()){//checking for daemon thread
4. [Link]("daemon thread work");
5. }
6. else{
7. [Link]("user thread work");
8. }
9. }
10. public static void main(String[] args){
11. TestDaemonThread1 t1=new TestDaemonThread1();//creating thread
12. TestDaemonThread1 t2=new TestDaemonThread1();
13. TestDaemonThread1 t3=new TestDaemonThread1();
14.
15. [Link](true);//now t1 is daemon thread
16.
17. [Link]();//starting threads
18. [Link]();
19. [Link]();
20. }
21.}
Test it Now
Output:
daemon thread work
user thread work
user thread work
Note: If you want to make a user thread as Daemon, it must not be started otherwise
it will throw IllegalThreadStateException.
File: [Link]
1. class TestDaemonThread2 extends Thread{
2. public void run(){
3. [Link]("Name: "+[Link]().getName());
4. [Link]("Daemon: "+[Link]().isDaemon());
5. }
6.
7. public static void main(String[] args){
8. TestDaemonThread2 t1=new TestDaemonThread2();
9. TestDaemonThread2 t2=new TestDaemonThread2();
10. [Link]();
11. [Link](true);//will throw exception here
12. [Link]();
13. }
14.}
Test it Now
Output:
exception in thread main: [Link]
Java Thread Pool
Java Thread pool represents a group of worker threads that are waiting for the
job and reused many times.
In the case of a thread pool, a group of fixed-size threads is created. A thread
from the thread pool is pulled out and assigned a job by the service provider.
After completion of the job, the thread is contained in the thread pool again.
Thread Pool Methods
newFixedThreadPool(int s): The method creates a thread pool of the fixed size
s.
newCachedThreadPool(): The method creates a new thread pool that creates
the new threads when needed but will still use the previously created thread
whenever they are available to use.
newSingleThreadExecutor(): The method creates a new thread.
Advantage of Java Thread Pool
Better performance It saves time because there is no need to create a new
thread.
Real time usage
It is used in Servlet and JSP where the container creates a thread pool to
process the request.
Example of Java Thread Pool
Let's see a simple example of the Java thread pool using ExecutorService and
Executors.
File: [Link]
1. import [Link];
2. import [Link];
3. class WorkerThread implements Runnable {
4. private String message;
5. public WorkerThread(String s){
6. [Link]=s;
7. }
8. public void run() {
9. [Link]([Link]().getName()+" (Start) message =
"+message);
10. processmessage();//call processmessage method that sleeps the thread f
or 2 seconds
11. [Link]([Link]().getName()+" (End)");//prints th
read name
12. }
13. private void processmessage() {
14. try { [Link](2000); } catch (InterruptedException e) { [Link]
ace(); }
15. }
16.}
File: [Link]
1. public class TestThreadPool {
2. public static void main(String[] args) {
3. ExecutorService executor = [Link](5);//creating a
pool of 5 threads
4. for (int i = 0; i < 10; i++) {
5. Runnable worker = new WorkerThread("" + i);
6. [Link](worker);//calling execute method of ExecutorService
7. }
8. [Link]();
9. while (![Link]()) { }
10.
11. [Link]("Finished all threads");
12. }
13. }
Output:
pool-1-thread-1 (Start) message = 0
pool-1-thread-2 (Start) message = 1
pool-1-thread-3 (Start) message = 2
pool-1-thread-5 (Start) message = 4
pool-1-thread-4 (Start) message = 3
pool-1-thread-2 (End)
pool-1-thread-2 (Start) message = 5
pool-1-thread-1 (End)
pool-1-thread-1 (Start) message = 6
pool-1-thread-3 (End)
pool-1-thread-3 (Start) message = 7
pool-1-thread-4 (End)
pool-1-thread-4 (Start) message = 8
pool-1-thread-5 (End)
pool-1-thread-5 (Start) message = 9
pool-1-thread-2 (End)
pool-1-thread-1 (End)
pool-1-thread-4 (End)
pool-1-thread-3 (End)
pool-1-thread-5 (End)
Finished all threads
Thread Pool Example: 2
Let's see another example of the thread pool.
FileName: [Link]
1. // important import statements
2. import [Link];
3. import [Link];
4. import [Link];
5. import [Link];
6.
7.
8. class Tasks implements Runnable
9. {
[Link] String taskName;
11.
12.// constructor of the class Tasks
[Link] Tasks(String str)
14.{
15.// initializing the field taskName
[Link] = str;
17.}
18.
19.// Printing the task name and then sleeps for 1 sec
20.// The complete process is getting repeated five times
[Link] void run()
22.{
[Link]
24.{
[Link] (int j = 0; j <= 5; j++)
26.{
[Link] (j == 0)
28.{
[Link] dt = new Date();
[Link] sdf = new SimpleDateFormat("hh : mm : ss");
31.
32.//prints the initialization time for every task
[Link]("Initialization time for the task name: "+ taskName + " = "
+ [Link](dt));
34.
35.}
[Link]
37.{
[Link] dt = new Date();
[Link] sdf = new SimpleDateFormat("hh : mm : ss");
40.
41.// prints the execution time for every task
[Link]("Time of execution for the task name: " + taskName + " = "
+[Link](dt));
43.
44.}
45.
46.// 1000ms = 1 sec
[Link](1000);
48.}
49.
[Link](taskName + " is complete.");
51.}
52.
[Link](InterruptedException ie)
54.{
[Link]();
56.}
57.}
58.}
59.
[Link] class ThreadPoolExample
61.{
62.// Maximum number of threads in the thread pool
[Link] final int MAX_TH = 3;
64.
65.// main method
[Link] static void main(String argvs[])
67.{
68.// Creating five new tasks
[Link] rb1 = new Tasks("task 1");
[Link] rb2 = new Tasks("task 2");
[Link] rb3 = new Tasks("task 3");
[Link] rb4 = new Tasks("task 4");
[Link] rb5 = new Tasks("task 5");
74.
75.// creating a thread pool with MAX_TH number of
76.// threads size the pool size is fixed
[Link] pl = [Link](MAX_TH);
78.
79.// passes the Task objects to the pool to execute (Step 3)
[Link](rb1);
[Link](rb2);
[Link](rb3);
[Link](rb4);
[Link](rb5);
85.
86.// pool is shutdown
[Link]();
88.}
89.}
Output:
Initialization time for the task name: task 1 = 06 : 13 : 02
Initialization time for the task name: task 2 = 06 : 13 : 02
Initialization time for the task name: task 3 = 06 : 13 : 02
Time of execution for the task name: task 1 = 06 : 13 : 04
Time of execution for the task name: task 2 = 06 : 13 : 04
Time of execution for the task name: task 3 = 06 : 13 : 04
Time of execution for the task name: task 1 = 06 : 13 : 05
Time of execution for the task name: task 2 = 06 : 13 : 05
Time of execution for the task name: task 3 = 06 : 13 : 05
Time of execution for the task name: task 1 = 06 : 13 : 06
Time of execution for the task name: task 2 = 06 : 13 : 06
Time of execution for the task name: task 3 = 06 : 13 : 06
Time of execution for the task name: task 1 = 06 : 13 : 07
Time of execution for the task name: task 2 = 06 : 13 : 07
Time of execution for the task name: task 3 = 06 : 13 : 07
Time of execution for the task name: task 1 = 06 : 13 : 08
Time of execution for the task name: task 2 = 06 : 13 : 08
Time of execution for the task name: task 3 = 06 : 13 : 08
task 2 is complete.
Initialization time for the task name: task 4 = 06 : 13 : 09
task 1 is complete.
Initialization time for the task name: task 5 = 06 : 13 : 09
task 3 is complete.
Time of execution for the task name: task 4 = 06 : 13 : 10
Time of execution for the task name: task 5 = 06 : 13 : 10
Time of execution for the task name: task 4 = 06 : 13 : 11
Time of execution for the task name: task 5 = 06 : 13 : 11
Time of execution for the task name: task 4 = 06 : 13 : 12
Time of execution for the task name: task 5 = 06 : 13 : 12
Time of execution for the task name: task 4 = 06 : 13 : 13
Time of execution for the task name: task 5 = 06 : 13 : 13
Time of execution for the task name: task 4 = 06 : 13 : 14
Time of execution for the task name: task 5 = 06 : 13 : 14
task 4 is complete.
task 5 is complete.
Explanation: It is evident by looking at the output of the program that tasks 4
and 5 are executed only when the thread has an idle thread. Until then, the
extra tasks are put in the queue.
The takeaway from the above example is when one wants to execute 50 tasks
but is not willing to create 50 threads. In such a case, one can create a pool of
10 threads. Thus, 10 out of 50 tasks are assigned, and the rest are put in the
queue. Whenever any thread out of 10 threads becomes idle, it picks up the
11th task. The other pending tasks are treated the same way.
Risks involved in Thread Pools
The following are the risk involved in the thread pools.
Deadlock: It is a known fact that deadlock can come in any program that
involves multithreading, and a thread pool introduces another scenario of
deadlock. Consider a scenario where all the threads that are executing are
waiting for the results from the threads that are blocked and waiting in the
queue because of the non-availability of threads for the execution.
Thread Leakage: Leakage of threads occurs when a thread is being removed
from the pool to execute a task but is not returning to it after the completion
of the task. For example, when a thread throws the exception and the pool
class is not able to catch this exception, then the thread exits and reduces the
thread pool size by 1. If the same thing repeats a number of times, then there
are fair chances that the pool will become empty, and hence, there are no
threads available in the pool for executing other requests.
Resource Thrashing: A lot of time is wasted in context switching among threads
when the size of the thread pool is very large. Whenever there are more
threads than the optimal number may cause the starvation problem, and it
leads to resource thrashing.
Points to Remember
Do not queue the tasks that are concurrently waiting for the results obtained
from the other tasks. It may lead to a deadlock situation, as explained above.
Care must be taken whenever threads are used for the operation that is long-
lived. It may result in the waiting of thread forever and will finally lead to the
leakage of the resource.
In the end, the thread pool has to be ended explicitly. If it does not happen,
then the program continues to execute, and it never ends. Invoke the
shutdown() method on the thread pool to terminate the executor. Note that if
someone tries to send another task to the executor after shutdown, it will
throw a RejectedExecutionException.
One needs to understand the tasks to effectively tune the thread pool. If the
given tasks are contrasting, then one should look for pools for executing
different varieties of tasks so that one can properly tune them.
To reduce the probability of running JVM out of memory, one can control the
maximum threads that can run in JVM. The thread pool cannot create new
threads after it has reached the maximum limit.
A thread pool can use the same used thread if the thread has finished its
execution. Thus, the time and resources used for the creation of a new thread
are saved.
Tuning the Thread Pool
The accurate size of a thread pool is decided by the number of available
processors and the type of tasks the threads have to execute. If a system has
the P processors that have only got the computation type processes, then the
maximum size of the thread pool of P or P + 1 achieves the maximum
efficiency. However, the tasks may have to wait for I/O, and in such a scenario,
one has to take into consideration the ratio of the waiting time (W) and the
service time (S) for the request; resulting in the maximum size of the pool P *
(1 + W / S) for the maximum efficiency.
Conclusion
A thread pool is a very handy tool for organizing applications, especially on
the server-side. Concept-wise, a thread pool is very easy to comprehend.
However, one may have to look at a lot of issues when dealing with a thread
pool. It is because the thread pool comes with some risks involved it (risks are
discussed above).
ThreadGroup in Java
Java provides a convenient way to group multiple threads in a single object. In
such a way, we can suspend, resume or interrupt a group of threads by a
single method call.
Note: Now suspend(), resume() and stop() methods are deprecated.
Java thread group is implemented by [Link] class.
A ThreadGroup represents a set of threads. A thread group can also include
the other thread group. The thread group creates a tree in which every thread
group except the initial thread group has a parent.
A thread is allowed to access information about its own thread group, but it
cannot access the information about its thread group's parent thread group or
any other thread groups.
Constructors of ThreadGroup class
There are only two constructors of ThreadGroup class.
No Constructor Description
.
1) ThreadGroup(String name) creates a thread group with given nam
2) ThreadGroup(ThreadGroup parent, String creates a thread group with a giv
name) group and name.
Methods of ThreadGroup class
There are many methods in ThreadGroup class. A list of ThreadGroup methods
is given below.
S.N. Modifier and Method Description
Type
1) void checkAccess() This method determines if the
running thread has permission to m
thread group.
2) int activeCount() This method returns an estimate of t
of active threads in the thread gro
subgroups.
3) int activeGroupCount() This method returns an estimate of t
of active groups in the thread gro
subgroups.
4) void destroy() This method destroys the thread gro
of its subgroups.
5) int enumerate(Thread[] list) This method copies into the spec
every active thread in the thread gro
subgroups.
6) int getMaxPriority() This method returns the maximum
the thread group.
7) String getName() This method returns the name of
group.
8) ThreadGroup getParent() This method returns the parent of
group.
9) void interrupt() This method interrupts all threads in
group.
10) boolean isDaemon() This method tests if the thread g
daemon thread group.
11) void setDaemon(boolean This method changes the daemon st
daemon) thread group.
12) boolean isDestroyed() This method tests if this thread group
destroyed.
13) void list() This method prints information
thread group to the standard output
14) boolean parentOf(ThreadGroup g This method tests if the thread grou
the thread group argument or o
ancestor thread groups.
15) void suspend() This method is used to suspend all
the thread group.
16) void resume() This method is used to resume all
the thread group which was suspen
suspend() method.
17) void setMaxPriority(int pri) This method sets the maximum prio
group.
18) void stop() This method is used to stop all thre
thread group.
19) String toString() This method returns a string represe
the Thread group.
Let's see a code to group multiple threads.
1. ThreadGroup tg1 = new ThreadGroup("Group A");
2. Thread t1 = new Thread(tg1,new MyRunnable(),"one");
3. Thread t2 = new Thread(tg1,new MyRunnable(),"two");
4. Thread t3 = new Thread(tg1,new MyRunnable(),"three");
Now all 3 threads belong to one group. Here, tg1 is the thread group name,
MyRunnable is the class that implements Runnable interface and "one", "two"
and "three" are the thread names.
Now we can interrupt all threads by a single line of code only.
1. [Link]().getThreadGroup().interrupt();
ThreadGroup Example
File: [Link]
1. public class ThreadGroupDemo implements Runnable{
2. public void run() {
3. [Link]([Link]().getName());
4. }
5. public static void main(String[] args) {
6. ThreadGroupDemo runnable = new ThreadGroupDemo();
7. ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
8.
9. Thread t1 = new Thread(tg1, runnable,"one");
10. [Link]();
11. Thread t2 = new Thread(tg1, runnable,"two");
12. [Link]();
13. Thread t3 = new Thread(tg1, runnable,"three");
14. [Link]();
15.
16. [Link]("Thread Group Name: "+[Link]());
17. [Link]();
18.
19. }
20. }
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
[Link][name=Parent ThreadGroup,maxpri=10]
Thread Pool Methods Example: int
activeCount()
Let's see how one can use the method activeCount().
FileName: [Link]
1. // code that illustrates the activeCount() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 1000; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.}
31.}
32.}
33.
[Link] class ActiveCountExample
35.{
36.// main method
[Link] static void main(String argvs[])
38.{
39.// creating the thread group
[Link] tg = new ThreadGroup("The parent group of threads");
41.
[Link] th1 = new ThreadNew("first", tg);
[Link]("Starting the first");
44.
[Link] th2 = new ThreadNew("second", tg);
[Link]("Starting the second");
47.
48.// checking the number of active thread by invoking the activeCount() method
[Link]("The total number of active threads are: " + [Link]()
);
50.}
51.}
Output:
Starting the first
Starting the second
The total number of active threads are: 2
Thread Pool Methods Example: int
activeGroupCount()
Now, we will learn how one can use the activeGroupCount() method in the
code.
FileName: [Link]
1. // Java code illustrating the activeGroupCount() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class ActiveGroupCountExample
38.{
39.// main method
[Link] static void main(String argvs[])
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("The parent group of threads");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
53.// checking the number of active thread by invoking the activeGroupCount() m
ethod
[Link]("The total number of active thread groups are: " + [Link]
GroupCount());
55.}
56.}
Output:
Starting the first
Starting the second
The total number of active thread groups are: 1
the second thread has finished executing
the first thread has finished executing
Thread Pool Methods Example: void destroy()
Now, we will learn how one can use the destroy() method in the code.
FileName: [Link]
1. // Code illustrating the destroy() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class DestroyExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
53.// waiting until the other threads has been finished
[Link]();
[Link]();
56.
57.// destroying the child thread group
[Link]();
[Link]([Link]() + " is destroyed.");
60.
61.// destroying the parent thread group
[Link]();
[Link]([Link]() + " is destroyed.");
64.}
65.}
Output:
Starting the first
Starting the second
the first thread has finished executing
the second thread has finished executing
the child group is destroyed.
the parent group is destroyed.
Thread Pool Methods Example: int
enumerate()
Now, we will learn how one can use the enumerate() method in the code.
FileName: [Link]
1. // Code illustrating the enumerate() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class EnumerateExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
53.// returning the number of threads kept in this array
[Link][] grp = new Thread[[Link]()];
[Link] cnt = [Link](grp);
[Link] (int j = 0; j < cnt; j++)
57.{
[Link]("Thread " + grp[j].getName() + " is found.");
59.}
60.}
61.}
Output:
Starting the first
Starting the second
Thread the first is found.
Thread the second is found.
the first thread has finished executing
the second thread has finished executing
Thread Pool Methods Example: int
getMaxPriority()
The following code shows the working of the getMaxPriority() method.
FileName: [Link]
1. // Code illustrating the getMaxPriority() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class GetMaxPriorityExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
[Link] priority = [Link]();
54.
[Link]("The maximum priority of the parent ThreadGroup: " + prio
rity);
56.
57.
58.}
59.}
Output:
Starting the first
Starting the second
The maximum priority of the parent ThreadGroup: 10
the first thread has finished executing
the second thread has finished executing
Thread Pool Methods Example:
ThreadGroup getParent()
Now, we will learn how one can use the getParent() method in the code.
FileName: [Link]
1. // Code illustrating the getParent() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered" + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class GetMaxPriorityExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
53.// printing the parent ThreadGroup
54.// of both child and parent threads
[Link]("The ParentThreadGroup for " + [Link]() + " is " + tg.
getParent().getName());
[Link]("The ParentThreadGroup for " + [Link]() + " is " + tg
[Link]().getName());
57.
58.
59.}
60.}
Output:
Starting the first
Starting the second
The ParentThreadGroup for the parent group is main
The ParentThreadGroup for the child group is the parent group
the first thread has finished executing
the second thread has finished executing
Thread Pool Methods Example: void
interrupt()
The following program illustrates how one can use the interrupt() method.
FileName: [Link]
1. // Code illustrating the interrupt() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered " + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class InterruptExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
53.// invoking the interrupt method
[Link]();
55.
56.}
57.}
Output:
Starting the first
Starting the second
The exception has been encountered [Link]: sleep
interrupted
The exception has been encountered [Link]: sleep
interrupted
the second thread has finished executing
the first thread has finished executing
Thread Pool Methods Example: boolean
isDaemon()
The following program illustrates how one can use the isDaemon() method.
FileName: [Link]
1. // Code illustrating the isDaemon() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered" + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class IsDaemonExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
[Link] ([Link]() == true)
54.{
[Link]("The group is a daemon group.");
56.}
[Link]
58.{
[Link]("The group is not a daemon group.");
60.}
61.
62.}
63.}
Output:
Starting the first
Starting the second
The group is not a daemon group.
the second thread has finished executing
the first thread has finished executing
Thread Pool Methods Example: boolean
isDestroyed()
The following program illustrates how one can use the isDestroyed() method.
FileName: [Link]
1. // Code illustrating the isDestroyed() method
2.
3. // import statement
4. import [Link].*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
[Link](String tName, ThreadGroup tgrp)
11.{
[Link](tgrp, tName);
[Link]();
14.}
15.
16.// overriding the run() method
[Link] void run()
18.{
19.
[Link] (int j = 0; j < 100; j++)
21.{
[Link]
23.{
[Link](5);
25.}
[Link] (InterruptedException e)
27.{
[Link]("The exception has been encountered" + e);
29.}
30.
31.}
32.
[Link]([Link]().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
[Link] class IsDestroyedExample
38.{
39.// main method
[Link] static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
[Link] tg = new ThreadGroup("the parent group");
44.
[Link] tg1 = new ThreadGroup(tg, "the child group");
46.
[Link] th1 = new ThreadNew("the first", tg);
[Link]("Starting the first");
49.
[Link] th2 = new ThreadNew("the second", tg);
[Link]("Starting the second");
52.
[Link] ([Link]() == true)
54.{
[Link]("The group has been destroyed.");
56.}
[Link]
58.{
[Link]("The group has not been destroyed.");
60.}
61.
62.}
63.}
Output:
Starting the first
Starting the second
The group has not been destroyed.
the first thread has finished executing
the second thread has finished executing
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.
Why use Synchronization?
The synchronization is mainly used to
1. To prevent thread interference.
2. To prevent consistency problem.
Types of Synchronization
There are two types of synchronization
1. Process Synchronization
2. Thread Synchronization
Here, we will discuss only 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:
1. By Using Synchronized Method
2. By Using Synchronized Block
3. By Using Static Synchronization
Concept of Lock in Java
Synchronization is built around an internal entity known as the lock or
monitor. Every object has a lock associated with it. 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.
From Java 5 the package [Link] contains several lock
implementations.
Understanding the problem without
Synchronization
In this example, there is no synchronization, so output is inconsistent. Let's see
the example:
[Link]
1. class Table{
2. void printTable(int n){//method not synchronized
3. for(int i=1;i<=5;i++){
4. [Link](n*i);
5. try{
6. [Link](400);
7. }catch(Exception e){[Link](e);}
8. }
9.
10. }
11.}
12.
[Link] MyThread1 extends Thread{
[Link] t;
15.MyThread1(Table t){
[Link].t=t;
17.}
[Link] void run(){
[Link](5);
20.}
21.
22.}
[Link] MyThread2 extends Thread{
[Link] t;
25.MyThread2(Table t){
[Link].t=t;
27.}
[Link] void run(){
[Link](100);
30.}
31.}
32.
[Link] TestSynchronization1{
[Link] static void main(String args[]){
[Link] obj = new Table();//only one object
36.MyThread1 t1=new MyThread1(obj);
37.MyThread2 t2=new MyThread2(obj);
[Link]();
[Link]();
40.}
41.}
Output:
5
100
10
200
15
300
20
400
25
500
Java Synchronized Method
If you 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
lock for that object and releases it when the thread completes its task.
[Link]
1. //example of java synchronized method
2. class Table{
3. synchronized void printTable(int n){//synchronized method
4. for(int i=1;i<=5;i++){
5. [Link](n*i);
6. try{
7. [Link](400);
8. }catch(Exception e){[Link](e);}
9. }
10.
11. }
12.}
13.
[Link] MyThread1 extends Thread{
[Link] t;
16.MyThread1(Table t){
[Link].t=t;
18.}
[Link] void run(){
[Link](5);
21.}
22.
23.}
[Link] MyThread2 extends Thread{
[Link] t;
26.MyThread2(Table t){
[Link].t=t;
28.}
[Link] void run(){
[Link](100);
31.}
32.}
33.
[Link] class TestSynchronization2{
[Link] static void main(String args[]){
[Link] obj = new Table();//only one object
37.MyThread1 t1=new MyThread1(obj);
38.MyThread2 t2=new MyThread2(obj);
[Link]();
[Link]();
41.}
42.}
Output:
5
10
15
20
25
100
200
300
400
500
Example of synchronized method by
using annonymous class
In this program, we have created the two threads by using the anonymous
class, so less coding is required.
[Link]
1. //Program of synchronized method by using annonymous class
2. class Table{
3. synchronized void printTable(int n){//synchronized method
4. for(int i=1;i<=5;i++){
5. [Link](n*i);
6. try{
7. [Link](400);
8. }catch(Exception e){[Link](e);}
9. }
10.
11. }
12.}
13.
[Link] class TestSynchronization3{
[Link] static void main(String args[]){
[Link] Table obj = new Table();//only one object
17.
[Link] t1=new Thread(){
[Link] void run(){
[Link](5);
21.}
22.};
[Link] t2=new Thread(){
[Link] void run(){
[Link](100);
26.}
27.};
28.
[Link]();
[Link]();
31.}
32.}
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.
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
o Synchronized block is used to lock an object for any shared resource.
o Scope of synchronized block is smaller than the method.
o A Java synchronized block doesn't allow more than one JVM, to provide
access control to a shared resource.
o The system performance may degrade because of the slower working of
synchronized keyword.
o Java synchronized block is more efficient than Java synchronized
method.
Syntax
1. synchronized (object reference expression) {
2. //code block
3. }
Example of Synchronized Block
Let's see the simple example of synchronized block.
[Link]
1. class Table
2. {
3. void printTable(int n){
4. synchronized(this){//synchronized block
5. for(int i=1;i<=5;i++){
6. [Link](n*i);
7. try{
8. [Link](400);
9. }catch(Exception e){[Link](e);}
10. }
11. }
12. }//end of the method
13.}
14.
[Link] MyThread1 extends Thread{
[Link] t;
17.MyThread1(Table t){
[Link].t=t;
19.}
[Link] void run(){
[Link](5);
22.}
23.
24.}
[Link] MyThread2 extends Thread{
[Link] t;
27.MyThread2(Table t){
[Link].t=t;
29.}
[Link] void run(){
[Link](100);
32.}
33.}
34.
[Link] class TestSynchronizedBlock1{
[Link] static void main(String args[]){
[Link] obj = new Table();//only one object
38.MyThread1 t1=new MyThread1(obj);
39.MyThread2 t2=new MyThread2(obj);
[Link]();
[Link]();
42.}
43.}
Output:
5
10
15
20
25
100
200
300
400
500
Synchronized Block Example Using Anonymous
Class
[Link]
1. // A Sender class
2. class Sender
3. {
4. public void SenderMsg(String msg)
5. {
6. [Link]("\nSending a Message: " + msg);
7. try
8. {
9. [Link](800);
10. }
11. catch (Exception e)
12. {
13. [Link]("Thread interrupted.");
14. }
15. [Link]("\n" +msg+ "Sent");
16. }
17.}
18.// A Sender class for sending a message using Threads
[Link] SenderWThreads extends Thread
20.{
21. private String msg;
22. Sender sd;
23.
24. // Receiver method to receive a message object and a message to be sent
25. SenderWThreads(String m, Sender obj)
26. {
27. msg = m;
28. sd = obj;
29. }
30.
31. public void run()
32. {
33. // Checks that only one thread sends a message at a time.
34. synchronized(sd)
35. {
36. // synchronizing the sender object
37. [Link](msg);
38. }
39. }
40.}
41.// Driver Code
[Link] class ShynchronizedMultithreading
43.{
44. public static void main(String args[])
45. {
46. Sender sender = new Sender();
47. SenderWThreads sender1 = new SenderWThreads( "Hola " , sender);
[Link] sender2 = new SenderWThreads( "Welcome to Javatpoint w
ebsite ", sender);
49.
50. // Start two threads of SenderWThreads type
51. [Link]();
52. [Link]();
53.
54. // wait for threads to end
55. try
56. {
57. [Link]();
58. [Link]();
59. }
60. catch(Exception e)
61. {
62. [Link]("Interrupted");
63. }
64. }
65.}
Output:
Sending a Message: Hola
Hola Sent
Sending a Message: Welcome to Javatpoint website
Welcome to Javatpoint website Sent
Static Synchronization
If you make any static method as synchronized, the lock will be on the class
not on object.
Problem without static synchronization
Suppose there are two objects of a shared class (e.g. Table) named object1
and object2. In case of synchronized method and synchronized block there
cannot be interference between t1 and t2 or t3 and t4 because t1 and t2 both
refers to a common object that have a single lock. But there can be
interference between t1 and t3 or t2 and t4 because t1 acquires another lock
and t3 acquires another lock. We don't want interference between t1 and t3 or
t2 and t4. Static synchronization solves this problem.
Example of Static Synchronization
In this example we have used synchronized keyword on the static method to
perform static synchronization.
[Link]
1. class Table
2. {
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. [Link](n*i);
6. try{
7. [Link](400);
8. }catch(Exception e){}
9. }
10. }
11.}
[Link] MyThread1 extends Thread{
[Link] void run(){
[Link](1);
15.}
16.}
[Link] MyThread2 extends Thread{
[Link] void run(){
[Link](10);
20.}
21.}
[Link] MyThread3 extends Thread{
[Link] void run(){
[Link](100);
25.}
26.}
[Link] MyThread4 extends Thread{
[Link] void run(){
[Link](1000);
30.}
31.}
[Link] class TestSynchronization4{
[Link] 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();
[Link]();
[Link]();
[Link]();
[Link]();
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
Example of static synchronization by Using the
anonymous class
In this example, we are using anonymous class to create the threads.
[Link]
1. class Table{
2.
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. [Link](n*i);
6. try{
7. [Link](400);
8. }catch(Exception e){}
9. }
10. }
11.}
12.
[Link] class TestSynchronization5 {
[Link] static void main(String[] args) {
15.
16. Thread t1=new Thread(){
17. public void run(){
18. [Link](1);
19. }
20. };
21.
22. Thread t2=new Thread(){
23. public void run(){
24. [Link](10);
25. }
26. };
27.
28. Thread t3=new Thread(){
29. public void run(){
30. [Link](100);
31. }
32. };
33.
34. Thread t4=new Thread(){
35. public void run(){
36. [Link](1000);
37. }
38. };
39. [Link]();
40. [Link]();
41. [Link]();
42. [Link]();
43.
44.}
45.}
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
Synchronized block on a class lock:
The block synchronizes on the lock of the object denoted by the
reference .class name .class. A static synchronized method printTable(int n) in
class Table is equivalent to the following declaration:
1. static void printTable(int n) {
2. synchronized ([Link]) { // Synchronized block on class A
3. // ...
4. }
5. }
Deadlock in Java
Deadlock in Java is a part of multithreading. Deadlock can occur in a situation
when a thread is waiting for an object lock, that is acquired by another thread
and second thread is waiting for an object lock that is acquired by first thread.
Since, both threads are waiting for each other to release the lock, the
condition is called deadlock.
Example of Deadlock in Java
[Link]
1. public class TestDeadlockExample1 {
2. public static void main(String[] args) {
3. final String resource1 = "ratan jaiswal";
4. final String resource2 = "vimal jaiswal";
5. // t1 tries to lock resource1 then resource2
6. Thread t1 = new Thread() {
7. public void run() {
8. synchronized (resource1) {
9. [Link]("Thread 1: locked resource 1");
10.
11. try { [Link](100);} catch (Exception e) {}
12.
13. synchronized (resource2) {
14. [Link]("Thread 1: locked resource 2");
15. }
16. }
17. }
18. };
19.
20. // t2 tries to lock resource2 then resource1
21. Thread t2 = new Thread() {
22. public void run() {
23. synchronized (resource2) {
24. [Link]("Thread 2: locked resource 2");
25.
26. try { [Link](100);} catch (Exception e) {}
27.
28. synchronized (resource1) {
29. [Link]("Thread 2: locked resource 1");
30. }
31. }
32. }
33. };
34.
35.
36. [Link]();
37. [Link]();
38. }
39.}
Output:
Thread 1: locked resource 1
Thread 2: locked resource 2
More Complicated Deadlocks
A deadlock may also include more than two threads. The reason is that it can
be difficult to detect a deadlock. Here is an example in which four threads
have deadlocked:
Thread 1 locks A, waits for B
Thread 2 locks B, waits for C
Thread 3 locks C, waits for D
Thread 4 locks D, waits for A
Thread 1 waits for thread 2, thread 2 waits for thread 3, thread 3 waits for
thread 4, and thread 4 waits for thread 1.
How to avoid deadlock?
A solution for a problem is found at its roots. In deadlock it is the pattern of
accessing the resources A and B, is the main issue. To solve the issue we will
have to simply re-order the statements where the code is accessing shared
resources.
[Link]
1. public class DeadlockSolved {
2.
3. public static void main(String ar[]) {
4. DeadlockSolved test = new DeadlockSolved();
5.
6. final resource1 a = [Link] resource1();
7. final resource2 b = [Link] resource2();
8.
9. // Thread-1
[Link] b1 = new Runnable() {
11. public void run() {
12. synchronized (b) {
13. try {
14. /* Adding delay so that both threads can start trying to lock resourc
es */
15. [Link](100);
16. } catch (InterruptedException e) {
17. [Link]();
18. }
19. // Thread-1 have resource1 but need resource2 also
20. synchronized (a) {
21. [Link]("In block 1");
22. }
23. }
24. }
25.};
26.
27.// Thread-2
[Link] b2 = new Runnable() {
29. public void run() {
30. synchronized (b) {
31. // Thread-2 have resource2 but need resource1 also
32. synchronized (a) {
33. [Link]("In block 2");
34. }
35. }
36. }
37.};
38.
39.
40. new Thread(b1).start();
41. new Thread(b2).start();
42. }
43.
44. // resource1
45. private class resource1 {
46. private int i = 10;
47.
48. public int getI() {
49. return i;
50. }
51.
52. public void setI(int i) {
53. this.i = i;
54. }
55. }
56.
57. // resource2
58. private class resource2 {
59. private int i = 20;
60.
61. public int getI() {
62. return i;
63. }
64.
65. public void setI(int i) {
66. this.i = i;
67. }
68. }
69.}
Output:
In block 1
In block 2
In the above code, class DeadlockSolved solves the deadlock kind of situation.
It will help in avoiding deadlocks, and if encountered, in resolving them.
How to Avoid Deadlock in Java?
Deadlocks cannot be completely resolved. But we can avoid them by following
basic rules mentioned below:
1. Avoid Nested Locks: We must avoid giving locks to multiple threads,
this is the main reason for a deadlock condition. It normally happens
when you give locks to multiple threads.
2. Avoid Unnecessary Locks: The locks should be given to the important
threads. Giving locks to the unnecessary threads that cause the deadlock
condition.
3. Using Thread Join: A deadlock usually happens when one thread is
waiting for the other to finish. In this case, we can use join with a
maximum time that a thread will take.
Inter-thread Communication in
Java
Inter-thread communication or Co-operation is all about allowing
synchronized threads to communicate with each other.
Cooperation (Inter-thread communication) is a mechanism in which a thread is
paused running in its critical section and another thread is allowed to enter (or
lock) in the same critical section to be [Link] is implemented by following
methods of Object class:
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.
Method Description
public final void wait()throws InterruptedException It waits until object is notifie
public final void wait(long timeout)throws It waits for the specified
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:
1. public final void notify()
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor.
Syntax:
1. public final void notifyAll()
Understanding the process of inter-
thread communication
The point to point explanation of the above diagram is as follows:
1. Threads enter to acquire lock.
2. Lock is acquired by on thread.
3. Now thread goes to waiting state if you call wait() method on the object.
Otherwise it releases the lock and exits.
4. If you call notify() or notifyAll() method, thread moves to the notified
state (runnable state).
5. Now thread is available to acquire lock.
6. After completion of the task, thread releases the lock and exits the
monitor state of the object.
Why wait(), notify() and notifyAll() methods are
defined in Object class not Thread class?
It is because they are related to lock and object has a lock.
Difference between wait and sleep?
Let's see the important differences between wait and sleep methods.
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the
It is a method of Object class It is a method of Thread class
It is the non-static method It is the static method
It should be notified by notify() or notifyAll() After the specified amount of time
methods completed.
Example of Inter Thread Communication in Java
Let's see the simple example of inter thread communication.
[Link]
1. class Customer{
2. int amount=10000;
3.
4. synchronized void withdraw(int amount){
5. [Link]("going to withdraw...");
6.
7. if([Link]<amount){
8. [Link]("Less balance; waiting for deposit...");
9. try{wait();}catch(Exception e){}
10.}
[Link]-=amount;
[Link]("withdraw completed...");
13.}
14.
[Link] void deposit(int amount){
[Link]("going to deposit...");
[Link]+=amount;
[Link]("deposit completed... ");
[Link]();
20.}
21.}
22.
[Link] Test{
[Link] static void main(String args[]){
[Link] Customer c=new Customer();
[Link] Thread(){
[Link] void run(){[Link](15000);}
28.}.start();
[Link] Thread(){
[Link] void run(){[Link](10000);}
31.}.start();
32.
33.}}
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.
The 3 methods provided by the Thread class for interrupting a thread
o public void interrupt()
o public static boolean interrupted()
o public boolean isInterrupted()
Example of interrupting a thread that
stops working
In this example, after interrupting the thread, we are propagating it, so it will
stop working. If we don't want to stop the thread, we can handle it where
sleep() or wait() method is invoked. Let's first see the example where we are
propagating the exception.
[Link]
1. class TestInterruptingThread1 extends Thread{
2. public void run(){
3. try{
4. [Link](1000);
5. [Link]("task");
6. }catch(InterruptedException e){
7. throw new RuntimeException("Thread interrupted..."+e);
8. }
9.
10.}
11.
[Link] static void main(String args[]){
13.TestInterruptingThread1 t1=new TestInterruptingThread1();
[Link]();
[Link]{
[Link]();
17.}catch(Exception e){[Link]("Exception handled "+e);}
18.
19.}
20.}
Test it Now
Output:
Exception in thread-0
[Link]: Thread interrupted...
[Link]: sleep interrupted
at [Link]([Link])
Example of interrupting a thread that
doesn't stop working
In this example, after interrupting the thread, we handle the exception, so it
will break out the sleeping but will not stop working.
[Link]
1. class TestInterruptingThread2 extends Thread{
2. public void run(){
3. try{
4. [Link](1000);
5. [Link]("task");
6. }catch(InterruptedException e){
7. [Link]("Exception handled "+e);
8. }
9. [Link]("thread is running...");
10.}
11.
[Link] static void main(String args[]){
13.TestInterruptingThread2 t1=new TestInterruptingThread2();
[Link]();
15.
[Link]();
17.
18.}
19.}
Test it Now
download this example
Output:
Exception handled
[Link]: sleep interrupted
thread is running...
Example of interrupting thread that
behaves normally
If thread is not in sleeping or waiting state, calling the interrupt() method sets
the interrupted flag to true that can be used to stop the thread by the java
programmer later.
[Link]
1. class TestInterruptingThread3 extends Thread{
2.
3. public void run(){
4. for(int i=1;i<=5;i++)
5. [Link](i);
6. }
7.
8. public static void main(String args[]){
9. TestInterruptingThread3 t1=new TestInterruptingThread3();
[Link]();
11.
[Link]();
13.
14.}
15.}
Test it Now
Output:
1
2
3
4
5
What about isInterrupted and
interrupted method?
The isInterrupted() method returns the interrupted flag either true or false. The
static interrupted() method returns the interrupted flag afterthat it sets the
flag to false if it is true.
[Link]
1. public class TestInterruptingThread4 extends Thread{
2.
3. public void run(){
4. for(int i=1;i<=2;i++){
5. if([Link]()){
6. [Link]("code for interrupted thread");
7. }
8. else{
9. [Link]("code for normal thread");
10.}
11.
12.}//end of for loop
13.}
14.
[Link] static void main(String args[]){
16.
17.TestInterruptingThread4 t1=new TestInterruptingThread4();
18.TestInterruptingThread4 t2=new TestInterruptingThread4();
19.
[Link]();
[Link]();
22.
[Link]();
24.
25.}
26.}
Test it Now
Output:
Code for interrupted thread
code for normal thread
code for normal thread
code for normal thread