0% found this document useful (0 votes)
10 views125 pages

Unit Iv R1

Uploaded by

kishore0331
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views125 pages

Unit Iv R1

Uploaded by

kishore0331
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 125

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) Thread.Stat 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


Thread.Unc 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 Thread.getState() method. The java.lang.Thread.State class of Java
provides the constants ENUM to represent the state of a thread. These
constants are:

1. public static final Thread.State NEW

It represents the first state of a thread that is the NEW state.

1. public static final Thread.State RUNNABLE

It represents the runnable state.It means a thread is waiting in the queue to


run.

1. public static final Thread.State BLOCKED

It represents the blocked state. In this state, the thread is waiting to acquire a
lock.

1. public static final Thread.State WAITING

It represents the waiting state. A thread will go to this state when it invokes
the Object.wait() method, or Thread.join() method with no timeout. A thread in
the waiting state is waiting for another thread to complete its task.

1. public static final Thread.State 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 Thread.State 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: ThreadState.java

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
11.Thread.sleep(100);
12.}
13.catch (InterruptedException ie)
14.{
15.ie.printStackTrace();
16.}
17.
18.
19.System.out.println("The state of thread t1 while it invoked the method join() o
n thread t2 -"+ ThreadState.t1.getState());
20.
21.// try-catch block
22.try
23.{
24.Thread.sleep(200);
25.}
26.catch (InterruptedException ie)
27.{
28.ie.printStackTrace();
29.}
30.}
31.}
32.
33.// ThreadState class implements the interface Runnable
34.public class ThreadState implements Runnable
35.{
36.public static Thread t1;
37.public static ThreadState obj;
38.
39.// main method
40.public static void main(String argvs[])
41.{
42.// creating an object of the class ThreadState
43.obj = new ThreadState();
44.t1 = new Thread(obj);
45.
46.// thread t1 is spawned
47.// The thread t1 is currently in the NEW state.
48.System.out.println("The state of thread t1 after spawning it - " + t1.getState());
49.
50.// invoking the start() method on
51.// the thread t1
52.t1.start();
53.
54.// thread t1 is moved to the Runnable state
55.System.out.println("The state of thread t1 after invoking the method start() on
it - " + t1.getState());
56.}
57.
58.public void run()
59.{
60.ABC myObj = new ABC();
61.Thread t2 = new Thread(myObj);
62.
63.// thread t2 is created and is currently in the NEW state.
64.System.out.println("The state of thread t2 after spawning it - "+ t2.getState());
65.t2.start();
66.
67.// thread t2 is moved to the runnable state
68.System.out.println("the state of thread t2 after calling the method start() on it -
" + t2.getState());
69.
70.// try-catch block for the smooth flow of the program
71.try
72.{
73.// moving the thread t1 to the state timed waiting
74.Thread.sleep(200);
75.}
76.catch (InterruptedException ie)
77.{
78.ie.printStackTrace();
79.}
80.
81.System.out.println("The state of thread t2 after invoking the method sleep() on
it - "+ t2.getState() );
82.
83.// try-catch block for the smooth flow of the program
84.try
85.{
86.// waiting for thread t2 to complete its execution
87.t2.join();
88.}
89.catch (InterruptedException ie)
90.{
91.ie.printStackTrace();
92.}
93.System.out.println("The state of thread t2 when it has completed it's execution
- " + t2.getState());
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 thread.Thread 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 thread.JVM 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.
10.public Thread currentThread(): returns the reference of currently
executing thread.
11.public int getId(): returns the id of the thread.
12.public Thread.State getState(): returns the state of the thread.
13.public boolean isAlive(): tests if the thread is alive.
14.public void yield(): causes the currently executing thread object to
temporarily pause and allow other threads to execute.
15.public void suspend(): is used to suspend the thread(depricated).
16.public void resume(): is used to resume the suspended
thread(depricated).
17.public void stop(): is used to stop the thread(depricated).
18.public boolean isDaemon(): tests if the thread is a daemon thread.
19.public void setDaemon(boolean b): marks the thread as daemon or
user thread.
20.public void interrupt(): interrupts the thread.
21.public boolean isInterrupted(): tests if the thread has been
interrupted.
22.public 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: Multi.java

1. class Multi extends Thread{


2. public void run(){
3. System.out.println("thread is running...");
4. }
5. public static void main(String args[]){
6. Multi t1=new Multi();
7. t1.start();
8. }
9. }

Output:
thread is running...

2) Java Thread Example by implementing


Runnable interface
FileName: Multi3.java

1. class Multi3 implements Runnable{


2. public void run(){
3. System.out.println("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. t1.start();
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: MyThread1.java

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
10.t.start();
11.// getting the thread name by invoking the getName() method
12.String str = t.getName();
13.System.out.println(str);
14.}
15.}

Output:
My first thread

4) Using the Thread Class: Thread(Runnable r,


String name)
Observe the following program.

FileName: MyThread2.java

1. public class MyThread2 implements Runnable


2. {
3. public void run()
4. {
5. System.out.println("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
12.Runnable r1 = new MyThread2();
13.
14.// creating an object of the class Thread using Thread(Runnable r, String name
)
15.Thread th1 = new Thread(r1, "My new thread");
16.
17.// the start() method moves the thread to the active state
18.th1.start();
19.
20.// getting the thread name by invoking the getName() method
21.String str = th1.getName();
22.System.out.println(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.

Thread.sleep() 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 Thread.sleep() 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 Thread.sleep() 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: TestSleepMethod1.java

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{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}

6. System.out.println(i);
7. }
8. }
9. public static void main(String args[]){
10. TestSleepMethod1 t1=new TestSleepMethod1();
11. TestSleepMethod1 t2=new TestSleepMethod1();
12.
13. t1.start();
14. t2.start();
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: TestSleepMethod2.java

1. // important import statements


2. import java.lang.Thread;
3. import java.io.*;
4.
5.
6. public class TestSleepMethod2
7. {
8. // main method
9. public static void main(String argvs[])
10.{
11.
12.try {
13.for (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
18.Thread.sleep(1000);
19.
20.// displaying the value of the variable
21.System.out.println(j);
22.}
23.}
24.catch (Exception expn)
25.{
26.// catching the exception
27.System.out.println(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: TestSleepMethod3.java

1. // important import statements


2. import java.lang.Thread;
3. import java.io.*;
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
12.try
13.{
14.for (int j = 0; j < 5; j++)
15.{
16.
17.// it throws the exception IllegalArgumentException
18.// as the time is -ive which is -100
19.Thread.sleep(-100);
20.
21.// displaying the variable's value
22.System.out.println(j);
23.}
24.}
25.catch (Exception expn)
26.{
27.
28.// the exception iscaught here
29.System.out.println(expn);
30.}
31.}
32.}

Output:
java.lang.IllegalArgumentException: 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. System.out.println("running...");
4. }
5. public static void main(String args[]){
6. TestThreadTwice1 t1=new TestThreadTwice1();
7. t1.start();
8. t1.start();
9. }
10.}
Test it Now
Output:
running
Exception in thread "main" java.lang.IllegalThreadStateException

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: TestCallRun1.java

1. class TestCallRun1 extends Thread{


2. public void run(){
3. System.out.println("running...");
4. }
5. public static void main(String args[]){
6. TestCallRun1 t1=new TestCallRun1();
7. t1.run();//fine, but does not start a separate call stack
8. }
9. }
Test it Now

Output:
running...
Problem if you direct call run() method

FileName: TestCallRun2.java

1. class TestCallRun2 extends Thread{


2. public void run(){
3. for(int i=1;i<5;i++){
4. try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}
5. System.out.println(i);
6. }
7. }
8. public static void main(String args[]){
9. TestCallRun2 t1=new TestCallRun2();
10. TestCallRun2 t2=new TestCallRun2();
11.
12. t1.run();
13. t2.run();
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 java.lang.Thread 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 th.join(); 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: ThreadJoinExample.java

1. // A Java program for understanding


2. // the joining of threads
3.
4. // import statement
5. import java.io.*;
6.
7. // The ThreadJoin class is the child class of the class Thread
8. class ThreadJoin extends Thread
9. {
10.// overriding the run method
11.public void run()
12.{
13.for (int j = 0; j < 2; j++)
14.{
15.try
16.{
17.// sleeping the thread for 300 milli seconds
18.Thread.sleep(300);
19.System.out.println("The current thread name is: " + Thread.currentThread().get
Name());
20.}
21.// catch block for catching the raised exception
22.catch(Exception e)
23.{
24.System.out.println("The exception has been caught: " + e);
25.}
26.System.out.println( j );
27.}
28.}
29.}
30.
31.public class ThreadJoinExample
32.{
33.// main method
34.public static void main (String argvs[])
35.{
36.
37.// creating 3 threads
38.ThreadJoin th1 = new ThreadJoin();
39.ThreadJoin th2 = new ThreadJoin();
40.ThreadJoin th3 = new ThreadJoin();
41.
42.// thread th1 starts
43.th1.start();
44.
45.// starting the second thread after when
46.// the first thread th1 has ended or died.
47.try
48.{
49.System.out.println("The current thread name is: "+ Thread.currentThread().get
Name());
50.
51.// invoking the join() method
52.th1.join();
53.}
54.
55.// catch block for catching the raised exception
56.catch(Exception e)
57.{
58.System.out.println("The exception has been caught " + e);
59.}
60.
61.// thread th2 starts
62.th2.start();
63.
64.// starting the th3 thread after when the thread th2 has ended or died.
65.try
66.{
67.System.out.println("The current thread name is: " + Thread.currentThread().get
Name());
68.th2.join();
69.}
70.
71.// catch block for catching the raised exception
72.catch(Exception e)
73.{
74.System.out.println("The exception has been caught " + e);
75.}
76.
77.// thread th3 starts
78.th3.start();
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: ThreadJoinExample1.java

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. threadToInterrupt.interrupt();
9. }
10.}
11.
12.
13.public class ThreadJoinExample1
14.{
15.// main method
16.public static void main(String[] argvs)
17.{
18.try
19.{
20.// creating an object of the class ABC
21.ABC th1 = new ABC();
22.
23.th1.threadToInterrupt = Thread.currentThread();
24.th1.start();
25.
26.// invoking the join() method leads
27.// to the generation of InterruptedException
28.th1.join();
29.}
30.catch (InterruptedException ex)
31.{
32.System.out.println("The exception has been caught. " + ex);
33.}
34.}
35.}

Output:
The exception has been caught. java.lang.InterruptedException

Some More Examples of the join()


Method
Let' see some other examples.

Filename: TestJoinMethod1.java

1. class TestJoinMethod1 extends Thread{


2. public void run(){
3. for(int i=1;i<=5;i++){
4. try{
5. Thread.sleep(500);
6. }catch(Exception e){System.out.println(e);}
7. System.out.println(i);
8. }
9. }
10.public static void main(String args[]){
11. TestJoinMethod1 t1=new TestJoinMethod1();
12. TestJoinMethod1 t2=new TestJoinMethod1();
13. TestJoinMethod1 t3=new TestJoinMethod1();
14. t1.start();
15. try{
16. t1.join();
17. }catch(Exception e){System.out.println(e);}
18.
19. t2.start();
20. t3.start();
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: TestJoinMethod2.jav

1. class TestJoinMethod2 extends Thread{


2. public void run(){
3. for(int i=1;i<=5;i++){
4. try{
5. Thread.sleep(500);
6. }catch(Exception e){System.out.println(e);}
7. System.out.println(i);
8. }
9. }
10.public static void main(String args[]){
11. TestJoinMethod2 t1=new TestJoinMethod2();
12. TestJoinMethod2 t2=new TestJoinMethod2();
13. TestJoinMethod2 t3=new TestJoinMethod2();
14. t1.start();
15. try{
16. t1.join(1500);
17. }catch(Exception e){System.out.println(e);}
18.
19. t2.start();
20. t3.start();
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: TestMultiNaming1.java

1. class TestMultiNaming1 extends Thread{


2. public void run(){
3. System.out.println("running...");
4. }
5. public static void main(String args[]){
6. TestMultiNaming1 t1=new TestMultiNaming1();
7. TestMultiNaming1 t2=new TestMultiNaming1();
8. System.out.println("Name of t1:"+t1.getName());
9. System.out.println("Name of t2:"+t2.getName());
10.
11. t1.start();
12. t2.start();
13.
14. t1.setName("Sonoo Jaiswal");
15. System.out.println("After changing name of t1:"+t1.getName());
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: ThreadNamingExample.java

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 java.io.*;
7.
8. // The ThreadNameClass is the child class of the class Thread
9. class ThreadName extends Thread
10.{
11.
12.// constructor of the class
13.ThreadName(String threadName)
14.{
15.// invoking the constructor of
16.// the superclass, which is Thread class.
17.super(threadName);
18.}
19.
20.// overriding the method run()
21.public void run()
22.{
23.System.out.println(" The thread is executing....");
24.}
25.}
26.
27.public class ThreadNamingExample
28.{
29.// main method
30.public static void main (String argvs[])
31.{
32.// creating two threads and settting their name
33.// using the contructor of the class
34.ThreadName th1 = new ThreadName("JavaTpoint1");
35.ThreadName th2 = new ThreadName("JavaTpoint2");
36.
37.// invoking the getName() method to get the names
38.// of the thread created above
39.System.out.println("Thread - 1: " + th1.getName());
40.System.out.println("Thread - 2: " + th2.getName());
41.
42.
43.// invoking the start() method on both the threads
44.th1.start();
45.th2.start();
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: TestMultiNaming2.java

1. class TestMultiNaming2 extends Thread{


2. public void run(){
3. System.out.println(Thread.currentThread().getName());
4. }
5. public static void main(String args[]){
6. TestMultiNaming2 t1=new TestMultiNaming2();
7. TestMultiNaming2 t2=new TestMultiNaming2();
8.
9. t1.start();
10. t2.start();
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 java.lang.Thread.getPriority() method


returns the priority of the given thread.

public final void setPriority(int newPriority): The


java.lang.Thread.setPriority() 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: ThreadPriorityExample.java

1. // Importing the required classes


2. import java.lang.*;
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
10.public void run()
11.{
12.// the print statement
13.System.out.println("Inside the run() method");
14.}
15.
16.// the main method
17.public static void main(String argvs[])
18.{
19.// Creating threads with the help of ThreadPriorityExample class
20.ThreadPriorityExample th1 = new ThreadPriorityExample();
21.ThreadPriorityExample th2 = new ThreadPriorityExample();
22.ThreadPriorityExample 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
30.System.out.println("Priority of the thread th1 is : " + th1.getPriority());
31.
32.// 2nd Thread
33.// Display the priority of the thread
34.System.out.println("Priority of the thread th2 is : " + th2.getPriority());
35.
36.// 3rd Thread
37.// // Display the priority of the thread
38.System.out.println("Priority of the thread th2 is : " + th2.getPriority());
39.
40.// Setting priorities of above threads by
41.// passing integer arguments
42.th1.setPriority(6);
43.th2.setPriority(3);
44.th3.setPriority(9);
45.
46.// 6
47.System.out.println("Priority of the thread th1 is : " + th1.getPriority());
48.
49.// 3
50.System.out.println("Priority of the thread th2 is : " + th2.getPriority());
51.
52.// 9
53.System.out.println("Priority of the thread th3 is : " + th3.getPriority());
54.
55.// Main thread
56.
57.// Displaying name of the currently executing thread
58.System.out.println("Currently Executing The Thread : " + Thread.currentThread(
).getName());
59.
60.System.out.println("Priority of the main thread is : " + Thread.currentThread().g
etPriority());
61.
62.// Priority of the main thread is 10 now
63.Thread.currentThread().setPriority(10);
64.
65.System.out.println("Priority of the main thread is : " + Thread.currentThread().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: ThreadPriorityExample1.java

1. // importing the java.lang package


2. import java.lang.*;
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
10.public void run()
11.{
12.// the print statement
13.System.out.println("Inside the run() method");
14.}
15.
16.
17.// the main method
18.public static void main(String argvs[])
19.{
20.
21.// Now, priority of the main thread is set to 7
22.Thread.currentThread().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
29.System.out.println("Priority of the main thread is : " + Thread.currentThread().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
38.System.out.println("Priority of the thread th1 is : " + th1.getPriority());
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: IllegalArgumentException.java

1. // importing the java.lang package


2. import java.lang.*;
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
12.Thread.currentThread().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
19.System.out.println("Priority of the main thread is : " + Thread.currentThread().g
etPriority());
20.
21.}
22.}

When we execute the above program, we get the following exception:


Exception in thread "main" java.lang.IllegalArgumentException
at java.base/java.lang.Thread.setPriority(Thread.java:1141)
at IllegalArgumentException.main(IllegalArgumentException.java:12)

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 java.lang.Thread 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: MyThread.java

1. public class TestDaemonThread1 extends Thread{


2. public void run(){
3. if(Thread.currentThread().isDaemon()){//checking for daemon thread
4. System.out.println("daemon thread work");
5. }
6. else{
7. System.out.println("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. t1.setDaemon(true);//now t1 is daemon thread
16.
17. t1.start();//starting threads
18. t2.start();
19. t3.start();
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: MyThread.java

1. class TestDaemonThread2 extends Thread{


2. public void run(){
3. System.out.println("Name: "+Thread.currentThread().getName());
4. System.out.println("Daemon: "+Thread.currentThread().isDaemon());
5. }
6.
7. public static void main(String[] args){
8. TestDaemonThread2 t1=new TestDaemonThread2();
9. TestDaemonThread2 t2=new TestDaemonThread2();
10. t1.start();
11. t1.setDaemon(true);//will throw exception here
12. t2.start();
13. }
14.}
Test it Now

Output:

exception in thread main: java.lang.IllegalThreadStateException


Java Thread Pool
Java Thread pool represents a group of worker threads that are waiting for the
job and 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: WorkerThread.java
1. import java.util.concurrent.ExecutorService;
2. import java.util.concurrent.Executors;
3. class WorkerThread implements Runnable {
4. private String message;
5. public WorkerThread(String s){
6. this.message=s;
7. }
8. public void run() {
9. System.out.println(Thread.currentThread().getName()+" (Start) message =
"+message);
10. processmessage();//call processmessage method that sleeps the thread f
or 2 seconds
11. System.out.println(Thread.currentThread().getName()+" (End)");//prints th
read name
12. }
13. private void processmessage() {
14. try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTr
ace(); }
15. }
16.}

File: TestThreadPool.java

1. public class TestThreadPool {


2. public static void main(String[] args) {
3. ExecutorService executor = Executors.newFixedThreadPool(5);//creating a
pool of 5 threads
4. for (int i = 0; i < 10; i++) {
5. Runnable worker = new WorkerThread("" + i);
6. executor.execute(worker);//calling execute method of ExecutorService
7. }
8. executor.shutdown();
9. while (!executor.isTerminated()) { }
10.
11. System.out.println("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: ThreadPoolExample.java

1. // important import statements


2. import java.util.Date;
3. import java.util.concurrent.ExecutorService;
4. import java.util.concurrent.Executors;
5. import java.text.SimpleDateFormat;
6.
7.
8. class Tasks implements Runnable
9. {
10.private String taskName;
11.
12.// constructor of the class Tasks
13.public Tasks(String str)
14.{
15.// initializing the field taskName
16.taskName = str;
17.}
18.
19.// Printing the task name and then sleeps for 1 sec
20.// The complete process is getting repeated five times
21.public void run()
22.{
23.try
24.{
25.for (int j = 0; j <= 5; j++)
26.{
27.if (j == 0)
28.{
29.Date dt = new Date();
30.SimpleDateFormat sdf = new SimpleDateFormat("hh : mm : ss");
31.
32.//prints the initialization time for every task
33.System.out.println("Initialization time for the task name: "+ taskName + " = "
+ sdf.format(dt));
34.
35.}
36.else
37.{
38.Date dt = new Date();
39.SimpleDateFormat sdf = new SimpleDateFormat("hh : mm : ss");
40.
41.// prints the execution time for every task
42.System.out.println("Time of execution for the task name: " + taskName + " = "
+sdf.format(dt));
43.
44.}
45.
46.// 1000ms = 1 sec
47.Thread.sleep(1000);
48.}
49.
50.System.out.println(taskName + " is complete.");
51.}
52.
53.catch(InterruptedException ie)
54.{
55.ie.printStackTrace();
56.}
57.}
58.}
59.
60.public class ThreadPoolExample
61.{
62.// Maximum number of threads in the thread pool
63.static final int MAX_TH = 3;
64.
65.// main method
66.public static void main(String argvs[])
67.{
68.// Creating five new tasks
69.Runnable rb1 = new Tasks("task 1");
70.Runnable rb2 = new Tasks("task 2");
71.Runnable rb3 = new Tasks("task 3");
72.Runnable rb4 = new Tasks("task 4");
73.Runnable rb5 = new Tasks("task 5");
74.
75.// creating a thread pool with MAX_TH number of
76.// threads size the pool size is fixed
77.ExecutorService pl = Executors.newFixedThreadPool(MAX_TH);
78.
79.// passes the Task objects to the pool to execute (Step 3)
80.pl.execute(rb1);
81.pl.execute(rb2);
82.pl.execute(rb3);
83.pl.execute(rb4);
84.pl.execute(rb5);
85.
86.// pool is shutdown
87.pl.shutdown();
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 java.lang.ThreadGroup 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. Thread.currentThread().getThreadGroup().interrupt();

ThreadGroup Example
File: ThreadGroupDemo.java

1. public class ThreadGroupDemo implements Runnable{


2. public void run() {
3. System.out.println(Thread.currentThread().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. t1.start();
11. Thread t2 = new Thread(tg1, runnable,"two");
12. t2.start();
13. Thread t3 = new Thread(tg1, runnable,"three");
14. t3.start();
15.
16. System.out.println("Thread Group Name: "+tg1.getName());
17. tg1.list();
18.
19. }
20. }

Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]

Thread Pool Methods Example: int


activeCount()
Let's see how one can use the method activeCount().

FileName: ActiveCountExample.java

1. // code that illustrates the activeCount() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run method
17.public void run()
18.{
19.
20.for (int j = 0; j < 1000; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.}
31.}
32.}
33.
34.public class ActiveCountExample
35.{
36.// main method
37.public static void main(String argvs[])
38.{
39.// creating the thread group
40.ThreadGroup tg = new ThreadGroup("The parent group of threads");
41.
42.ThreadNew th1 = new ThreadNew("first", tg);
43.System.out.println("Starting the first");
44.
45.ThreadNew th2 = new ThreadNew("second", tg);
46.System.out.println("Starting the second");
47.
48.// checking the number of active thread by invoking the activeCount() method

49.System.out.println("The total number of active threads are: " + tg.activeCount()


);
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: ActiveGroupCountExample.java

1. // Java code illustrating the activeGroupCount() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class ActiveGroupCountExample
38.{
39.// main method
40.public static void main(String argvs[])
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("The parent group of threads");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// checking the number of active thread by invoking the activeGroupCount() m
ethod
54.System.out.println("The total number of active thread groups are: " + tg.active
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: DestroyExample.java
1. // Code illustrating the destroy() method
2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class DestroyExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// waiting until the other threads has been finished
54.th1.join();
55.th2.join();
56.
57.// destroying the child thread group
58.tg1.destroy();
59.System.out.println(tg1.getName() + " is destroyed.");
60.
61.// destroying the parent thread group
62.tg.destroy();
63.System.out.println(tg.getName() + " 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: EnumerateExample.java

1. // Code illustrating the enumerate() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class EnumerateExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// returning the number of threads kept in this array
54.Thread[] grp = new Thread[tg.activeCount()];
55.int cnt = tg.enumerate(grp);
56.for (int j = 0; j < cnt; j++)
57.{
58.System.out.println("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: GetMaxPriorityExample.java

1. // Code illustrating the getMaxPriority() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class GetMaxPriorityExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.int priority = tg.getMaxPriority();
54.
55.System.out.println("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: GetParentExample.java

1. // Code illustrating the getParent() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered" + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class GetMaxPriorityExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// printing the parent ThreadGroup
54.// of both child and parent threads
55.System.out.println("The ParentThreadGroup for " + tg.getName() + " is " + tg.
getParent().getName());
56.System.out.println("The ParentThreadGroup for " + tg1.getName() + " is " + tg
1.getParent().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: InterruptExample.java

1. // Code illustrating the interrupt() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered " + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class InterruptExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.// invoking the interrupt method
54.tg.interrupt();
55.
56.}
57.}

Output:
Starting the first
Starting the second
The exception has been encountered java.lang.InterruptedException: sleep
interrupted
The exception has been encountered java.lang.InterruptedException: 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: IsDaemonExample.java

1. // Code illustrating the isDaemon() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered" + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class IsDaemonExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.if (tg.isDaemon() == true)
54.{
55.System.out.println("The group is a daemon group.");
56.}
57.else
58.{
59.System.out.println("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: IsDestroyedExample.java

1. // Code illustrating the isDestroyed() method


2.
3. // import statement
4. import java.lang.*;
5.
6.
7. class ThreadNew extends Thread
8. {
9. // constructor of the class
10.ThreadNew(String tName, ThreadGroup tgrp)
11.{
12.super(tgrp, tName);
13.start();
14.}
15.
16.// overriding the run() method
17.public void run()
18.{
19.
20.for (int j = 0; j < 100; j++)
21.{
22.try
23.{
24.Thread.sleep(5);
25.}
26.catch (InterruptedException e)
27.{
28.System.out.println("The exception has been encountered" + e);
29.}
30.
31.}
32.
33.System.out.println(Thread.currentThread().getName() + " thread has finished e
xecuting");
34.}
35.}
36.
37.public class IsDestroyedExample
38.{
39.// main method
40.public static void main(String argvs[]) throws SecurityException, InterruptedE
xception
41.{
42.// creating the thread group
43.ThreadGroup tg = new ThreadGroup("the parent group");
44.
45.ThreadGroup tg1 = new ThreadGroup(tg, "the child group");
46.
47.ThreadNew th1 = new ThreadNew("the first", tg);
48.System.out.println("Starting the first");
49.
50.ThreadNew th2 = new ThreadNew("the second", tg);
51.System.out.println("Starting the second");
52.
53.if (tg.isDestroyed() == true)
54.{
55.System.out.println("The group has been destroyed.");
56.}
57.else
58.{
59.System.out.println("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 java.util.concurrent.locks 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:

TestSynchronization1.java

1. class Table{
2. void printTable(int n){//method not synchronized
3. for(int i=1;i<=5;i++){
4. System.out.println(n*i);
5. try{
6. Thread.sleep(400);
7. }catch(Exception e){System.out.println(e);}
8. }
9.
10. }
11.}
12.
13.class MyThread1 extends Thread{
14.Table t;
15.MyThread1(Table t){
16.this.t=t;
17.}
18.public void run(){
19.t.printTable(5);
20.}
21.
22.}
23.class MyThread2 extends Thread{
24.Table t;
25.MyThread2(Table t){
26.this.t=t;
27.}
28.public void run(){
29.t.printTable(100);
30.}
31.}
32.
33.class TestSynchronization1{
34.public static void main(String args[]){
35.Table obj = new Table();//only one object
36.MyThread1 t1=new MyThread1(obj);
37.MyThread2 t2=new MyThread2(obj);
38.t1.start();
39.t2.start();
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.

TestSynchronization2.java

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. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){System.out.println(e);}
9. }
10.
11. }
12.}
13.
14.class MyThread1 extends Thread{
15.Table t;
16.MyThread1(Table t){
17.this.t=t;
18.}
19.public void run(){
20.t.printTable(5);
21.}
22.
23.}
24.class MyThread2 extends Thread{
25.Table t;
26.MyThread2(Table t){
27.this.t=t;
28.}
29.public void run(){
30.t.printTable(100);
31.}
32.}
33.
34.public class TestSynchronization2{
35.public static void main(String args[]){
36.Table obj = new Table();//only one object
37.MyThread1 t1=new MyThread1(obj);
38.MyThread2 t2=new MyThread2(obj);
39.t1.start();
40.t2.start();
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.

TestSynchronization3.java

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. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){System.out.println(e);}
9. }
10.
11. }
12.}
13.
14.public class TestSynchronization3{
15.public static void main(String args[]){
16.final Table obj = new Table();//only one object
17.
18.Thread t1=new Thread(){
19.public void run(){
20.obj.printTable(5);
21.}
22.};
23.Thread t2=new Thread(){
24.public void run(){
25.obj.printTable(100);
26.}
27.};
28.
29.t1.start();
30.t2.start();
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.

TestSynchronizedBlock1.java

1. class Table
2. {
3. void printTable(int n){
4. synchronized(this){//synchronized block
5. for(int i=1;i<=5;i++){
6. System.out.println(n*i);
7. try{
8. Thread.sleep(400);
9. }catch(Exception e){System.out.println(e);}
10. }
11. }
12. }//end of the method
13.}
14.
15.class MyThread1 extends Thread{
16.Table t;
17.MyThread1(Table t){
18.this.t=t;
19.}
20.public void run(){
21.t.printTable(5);
22.}
23.
24.}
25.class MyThread2 extends Thread{
26.Table t;
27.MyThread2(Table t){
28.this.t=t;
29.}
30.public void run(){
31.t.printTable(100);
32.}
33.}
34.
35.public class TestSynchronizedBlock1{
36.public static void main(String args[]){
37.Table obj = new Table();//only one object
38.MyThread1 t1=new MyThread1(obj);
39.MyThread2 t2=new MyThread2(obj);
40.t1.start();
41.t2.start();
42.}
43.}

Output:
5
10
15
20
25
100
200
300
400
500

Synchronized Block Example Using Anonymous


Class
TestSynchronizedBlock2.java

1. // A Sender class
2. class Sender
3. {
4. public void SenderMsg(String msg)
5. {
6. System.out.println("\nSending a Message: " + msg);
7. try
8. {
9. Thread.sleep(800);
10. }
11. catch (Exception e)
12. {
13. System.out.println("Thread interrupted.");
14. }
15. System.out.println("\n" +msg+ "Sent");
16. }
17.}
18.// A Sender class for sending a message using Threads
19.class 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. sd.SenderMsg(msg);
38. }
39. }
40.}
41.// Driver Code
42.public class ShynchronizedMultithreading
43.{
44. public static void main(String args[])
45. {
46. Sender sender = new Sender();
47. SenderWThreads sender1 = new SenderWThreads( "Hola " , sender);
48.SenderWThreads sender2 = new SenderWThreads( "Welcome to Javatpoint w
ebsite ", sender);
49.
50. // Start two threads of SenderWThreads type
51. sender1.start();
52. sender2.start();
53.
54. // wait for threads to end
55. try
56. {
57. sender1.join();
58. sender2.join();
59. }
60. catch(Exception e)
61. {
62. System.out.println("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.

TestSynchronization4.java

1. class Table
2. {
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){}
9. }
10. }
11.}
12.class MyThread1 extends Thread{
13.public void run(){
14.Table.printTable(1);
15.}
16.}
17.class MyThread2 extends Thread{
18.public void run(){
19.Table.printTable(10);
20.}
21.}
22.class MyThread3 extends Thread{
23.public void run(){
24.Table.printTable(100);
25.}
26.}
27.class MyThread4 extends Thread{
28.public void run(){
29.Table.printTable(1000);
30.}
31.}
32.public class TestSynchronization4{
33.public static void main(String t[]){
34.MyThread1 t1=new MyThread1();
35.MyThread2 t2=new MyThread2();
36.MyThread3 t3=new MyThread3();
37.MyThread4 t4=new MyThread4();
38.t1.start();
39.t2.start();
40.t3.start();
41.t4.start();
42.}
43.}
Test it Now

Output:
1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

Example of static synchronization by Using the


anonymous class
In this example, we are using anonymous class to create the threads.

TestSynchronization5.javaHello

1. class Table{
2.
3. synchronized static void printTable(int n){
4. for(int i=1;i<=10;i++){
5. System.out.println(n*i);
6. try{
7. Thread.sleep(400);
8. }catch(Exception e){}
9. }
10. }
11.}
12.
13.public class TestSynchronization5 {
14.public static void main(String[] args) {
15.
16. Thread t1=new Thread(){
17. public void run(){
18. Table.printTable(1);
19. }
20. };
21.
22. Thread t2=new Thread(){
23. public void run(){
24. Table.printTable(10);
25. }
26. };
27.
28. Thread t3=new Thread(){
29. public void run(){
30. Table.printTable(100);
31. }
32. };
33.
34. Thread t4=new Thread(){
35. public void run(){
36. Table.printTable(1000);
37. }
38. };
39. t1.start();
40. t2.start();
41. t3.start();
42. t4.start();
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 (Table.class) { // 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


TestDeadlockExample1.java

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. System.out.println("Thread 1: locked resource 1");
10.
11. try { Thread.sleep(100);} catch (Exception e) {}
12.
13. synchronized (resource2) {
14. System.out.println("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. System.out.println("Thread 2: locked resource 2");
25.
26. try { Thread.sleep(100);} catch (Exception e) {}
27.
28. synchronized (resource1) {
29. System.out.println("Thread 2: locked resource 1");
30. }
31. }
32. }
33. };
34.
35.
36. t1.start();
37. t2.start();
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.

DeadlockSolved.java

1. public class DeadlockSolved {


2.
3. public static void main(String ar[]) {
4. DeadlockSolved test = new DeadlockSolved();
5.
6. final resource1 a = test.new resource1();
7. final resource2 b = test.new resource2();
8.
9. // Thread-1
10.Runnable 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. Thread.sleep(100);
16. } catch (InterruptedException e) {
17. e.printStackTrace();
18. }
19. // Thread-1 have resource1 but need resource2 also
20. synchronized (a) {
21. System.out.println("In block 1");
22. }
23. }
24. }
25.};
26.
27.// Thread-2
28.Runnable b2 = new Runnable() {
29. public void run() {
30. synchronized (b) {
31. // Thread-2 have resource2 but need resource1 also
32. synchronized (a) {
33. System.out.println("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 executed.It 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.

Test.java

1. class Customer{
2. int amount=10000;
3.
4. synchronized void withdraw(int amount){
5. System.out.println("going to withdraw...");
6.
7. if(this.amount<amount){
8. System.out.println("Less balance; waiting for deposit...");
9. try{wait();}catch(Exception e){}
10.}
11.this.amount-=amount;
12.System.out.println("withdraw completed...");
13.}
14.
15.synchronized void deposit(int amount){
16.System.out.println("going to deposit...");
17.this.amount+=amount;
18.System.out.println("deposit completed... ");
19.notify();
20.}
21.}
22.
23.class Test{
24.public static void main(String args[]){
25.final Customer c=new Customer();
26.new Thread(){
27.public void run(){c.withdraw(15000);}
28.}.start();
29.new Thread(){
30.public void run(){c.deposit(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.

TestInterruptingThread1.java

1. class TestInterruptingThread1 extends Thread{


2. public void run(){
3. try{
4. Thread.sleep(1000);
5. System.out.println("task");
6. }catch(InterruptedException e){
7. throw new RuntimeException("Thread interrupted..."+e);
8. }
9.
10.}
11.
12.public static void main(String args[]){
13.TestInterruptingThread1 t1=new TestInterruptingThread1();
14.t1.start();
15.try{
16.t1.interrupt();
17.}catch(Exception e){System.out.println("Exception handled "+e);}
18.
19.}
20.}
Test it Now

Output:
Exception in thread-0
java.lang.RuntimeException: Thread interrupted...
java.lang.InterruptedException: sleep interrupted
at A.run(A.java:7)

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.

TestInterruptingThread2.java

1. class TestInterruptingThread2 extends Thread{


2. public void run(){
3. try{
4. Thread.sleep(1000);
5. System.out.println("task");
6. }catch(InterruptedException e){
7. System.out.println("Exception handled "+e);
8. }
9. System.out.println("thread is running...");
10.}
11.
12.public static void main(String args[]){
13.TestInterruptingThread2 t1=new TestInterruptingThread2();
14.t1.start();
15.
16.t1.interrupt();
17.
18.}
19.}
Test it Now
download this example

Output:
Exception handled
java.lang.InterruptedException: 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.

TestInterruptingThread3.java

1. class TestInterruptingThread3 extends Thread{


2.
3. public void run(){
4. for(int i=1;i<=5;i++)
5. System.out.println(i);
6. }
7.
8. public static void main(String args[]){
9. TestInterruptingThread3 t1=new TestInterruptingThread3();
10.t1.start();
11.
12.t1.interrupt();
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.

TestInterruptingThread4.java

1. public class TestInterruptingThread4 extends Thread{


2.
3. public void run(){
4. for(int i=1;i<=2;i++){
5. if(Thread.interrupted()){
6. System.out.println("code for interrupted thread");
7. }
8. else{
9. System.out.println("code for normal thread");
10.}
11.
12.}//end of for loop
13.}
14.
15.public static void main(String args[]){
16.
17.TestInterruptingThread4 t1=new TestInterruptingThread4();
18.TestInterruptingThread4 t2=new TestInterruptingThread4();
19.
20.t1.start();
21.t1.interrupt();
22.
23.t2.start();
24.
25.}
26.}
Test it Now

Output:
Code for interrupted thread
code for normal thread
code for normal thread
code for normal thread

You might also like