Multithreading in Java
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.
AD
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.
AD
Java Thread Methods
S.N. Modifier and Type Method Descriptio
1) void start() It is used to
the executio
the thread.
2) void run() It is used to
an action f
thread.
3) static void sleep() It sleeps
thread for
specified
amount of t
4) static Thread currentThread() It returns
reference to
currently
executing
thread obje
5) void join() It waits fo
thread to di
6) int getPriority() It returns
priority of
thread.
7) void setPriority() It changes
priority of
thread.
8) String getName() It returns
name of
thread.
9) void setName() It changes
name of
thread.
10) long getId() It returns th
of the threa
11) boolean isAlive() It tests if
thread is ali
12) static void yield() It causes
currently
executing
thread obje
pause and a
other thread
execute
temporarily
13) void suspend() It is used
suspend
thread.
14) void resume() It is used
resume
suspended
thread.
15) void stop() It is used to
the thread.
16) void destroy() It is used
destroy
thread g
and all of
subgroups.
17) boolean isDaemon() It tests if
thread is
daemon thr
18) void setDaemon() It marks
thread
daemon or
thread.
19) void interrupt() It interrupts
thread.
20) boolean isinterrupted() It tests whe
the thread
been
interrupted.
21) static boolean interrupted() It tests whe
the cu
thread has b
interrupted.
22) static int activeCount() It returns
number
active threa
the cu
thread's th
group.
23) void checkAccess() It determin
the curr
running th
has permis
to modify
thread.
24) static boolean holdLock() It returns tr
and only if
current th
holds
monitor loc
the spec
object.
25) static void dumpStack() It is used
print a s
trace of
current th
to the stan
error stream
26) StackTraceElement[] getStackTrace() It returns
array of s
trace elem
representing
the stack d
of the threa
27) static int enumerate() It is used
copy e
active thre
thread g
and
subgroup
the spec
array.
28) [Link] getState() It is used
return the
of the threa
29) ThreadGroup getThreadGroup() It is used
return
thread grou
which
thread belo
30) String toString() It is used
return a s
representat
of this thr
including
thread's n
priority,
thread grou
31) void notify() It is used to
the notifica
for only
thread whic
waiting fo
particular
object.
32) void notifyAll() It is used to
the notifica
to all wa
threads o
particular
object.
33) void setContextClassLoader() It sets
context
ClassLoader
the Thread.
34) ClassLoader getContextClassLoader() It returns
context
ClassLoader
the thread.
35) static getDefaultUncaughtExceptionHandler() It returns
[Link] default han
invoked wh
thread abru
terminates
to an unca
exception.
36) static void setDefaultUncaughtExceptionHandler() It sets
default han
invoked wh
thread abru
terminates
to an unca
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.
AD
A terminated thread means the thread is no more in the system. In other words, the
thread is dead, and there is no way one can respawn (active after kill) the dead thread.
The following diagram shows the different states involved in the life cycle of a thread.
Implementation of Thread States
In Java, one can get the current state of a thread using the [Link]() method.
The [Link] class of Java provides the constants ENUM to represent
the state of a thread. These constants are:
1. public static final [Link] NEW
It represents the first state of a thread that is the NEW state.
1. public static final [Link] RUNNABLE
It represents the runnable [Link] means a thread is waiting in the queue to run.
1. public static final [Link] BLOCKED
It represents the blocked state. In this state, the thread is waiting to acquire a lock.
1. public static final [Link] WAITING
It represents the waiting state. A thread will go to this state when it invokes the
[Link]() method, or [Link]() method with no timeout. A thread in the waiting
state is waiting for another thread to complete its task.
1. public static final [Link] TIMED_WAITING
It represents the timed waiting state. The main difference between waiting and timed
waiting is the time constraint. Waiting has no time constraint, whereas timed waiting
has the time constraint. A thread invoking the following method reaches the timed
waiting state.
o sleep
o join with timeout
o wait with timeout
o parkUntil
o parkNanos
1. public static final [Link] TERMINATED
It represents the final state of a thread that is terminated or dead. A terminated thread
means it has completed its execution.
Java Program for Demonstrating Thread States
The following Java program shows some of the states of a thread defined above.
FileName: [Link]
1. // ABC class implements the interface Runnable
2. class ABC implements Runnable
3. {
4. public void run()
5. {
6.
7. // try-catch block
8. try
9. {
10. // moving thread t2 to the state timed waiting
11. [Link](100);
12. }
13. catch (InterruptedException ie)
14. {
15. [Link]();
16. }
17.
18.
19. [Link]("The state of thread t1 while it invoked the method join() o
n thread t2 -"+ [Link]());
20.
21. // try-catch block
22. try
23. {
24. [Link](200);
25. }
26. catch (InterruptedException ie)
27. {
28. [Link]();
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. [Link]("The state of thread t1 after spawning it - " + [Link]());
49.
50. // invoking the start() method on
51. // the thread t1
52. [Link]();
53.
54. // thread t1 is moved to the Runnable state
55. [Link]("The state of thread t1 after invoking the method start() on
it - " + [Link]());
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. [Link]("The state of thread t2 after spawning it - "+ [Link]());
65. [Link]();
66.
67. // thread t2 is moved to the runnable state
68. [Link]("the state of thread t2 after calling the method start() on it
- " + [Link]());
69.
70. // try-catch block for the smooth flow of the program
71. try
72. {
73. // moving the thread t1 to the state timed waiting
74. [Link](200);
75. }
76. catch (InterruptedException ie)
77. {
78. [Link]();
79. }
80.
81. [Link]("The state of thread t2 after invoking the method sleep() on
it - "+ [Link]() );
82.
83. // try-catch block for the smooth flow of the program
84. try
85. {
86. // waiting for thread t2 to complete its execution
87. [Link]();
88. }
89. catch (InterruptedException ie)
90. {
91. [Link]();
92. }
93. [Link]("The state of thread t2 when it has completed it's execution
- " + [Link]());
94. }
95.
96. }
Output:
The state of thread t1 after spawning it - NEW
The state of thread t1 after invoking the method start() on it - RUNNABLE
The state of thread t2 after spawning it - NEW
the state of thread t2 after calling the method start() on it - RUNNABLE
The state of thread t1 while it invoked the method join() on thread t2 -
TIMED_WAITING
The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING
The state of thread t2 when it has completed it's execution - TERMINATED
Explanation: Whenever we spawn a new thread, that thread attains the new state.
When the method start() is invoked on a thread, the thread scheduler moves that
thread to the runnable state. Whenever the join() method is invoked on any thread
instance, the current thread executing that statement has to wait for this thread to
finish its execution, i.e., move that thread to the terminated state. Therefore, before
the final print statement is printed on the console, the program invokes the method
join() on thread t2, making the thread t1 wait while the thread t2 finishes its execution
and thus, the thread t2 get to the terminated or dead state. Thread t1 goes to the
waiting state because it is waiting for thread t2 to finish it's execution as it has invoked
the method join() on thread t2.
Java Threads | How to create a thread in Java
There are two ways to create a thread:
1. By extending Thread class
2. By implementing Runnable interface.
Thread class:
Thread class provide constructors and methods to create and perform operations on
a [Link] class extends Object class and implements Runnable interface.
Commonly used Constructors of Thread class:
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
Commonly used methods of Thread class:
1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the [Link] calls the run()
method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to
sleep (temporarily cease execution) for the specified number of milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the specified
miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10. public Thread currentThread(): returns the reference of currently executing
thread.
11. public int getId(): returns the id of the thread.
12. public [Link] 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.
AD
1) Java Thread Example by extending Thread class
FileName: [Link]
1. class Multi extends Thread{
2. public void run(){
3. [Link]("thread is running...");
4. }
5. public static void main(String args[]){
6. Multi t1=new Multi();
7. [Link]();
8. }
9. }
Output:
thread is running...
2) Java Thread Example by implementing Runnable interface
FileName: [Link]
1. class Multi3 implements Runnable{
2. public void run(){
3. [Link]("thread is running...");
4. }
5.
6. public static void main(String args[]){
7. Multi3 m1=new Multi3();
8. Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
9. [Link]();
10. }
11. }
Output:
thread is running...
If you are not extending the Thread class, your class object would not be treated as a
thread object. So you need to explicitly create the Thread class object. We are passing
the object of your class that implements Runnable so that your class run() method may
execute.
3) Using the Thread Class: Thread(String Name)
We can directly use the Thread class to spawn new threads using the constructors
defined above.
FileName: [Link]
1. public class MyThread1
2. {
3. // Main method
4. public static void main(String argvs[])
5. {
6. // creating an object of the Thread class using the constructor Thread(String n
ame)
7. Thread t= new Thread("My first thread");
8.
9. // the start() method moves the thread to the active state
10. [Link]();
11. // getting the thread name by invoking the getName() method
12. String str = [Link]();
13. [Link](str);
14. }
15. }
Output:
My first thread
4) Using the Thread Class: Thread(Runnable r, String name)
Observe the following program.
FileName: [Link]
1. public class MyThread2 implements Runnable
2. {
3. public void run()
4. {
5. [Link]("Now the thread is running ...");
6. }
7.
8. // main method
9. public static void main(String argvs[])
10. {
11. // creating an object of the class MyThread2
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. [Link]();
19.
20. // getting the thread name by invoking the getName() method
21. String str = [Link]();
22. [Link](str);
23. }
24. }
Output:
My new thread
Now the thread is running ...