Multi-Threading in Java
Process
A process is an instance of a program that is being executed. When a program runs, the operating system
creates a process to manage its execution.
Thread
A thread is the smallest unit of execution within a process. A process can have multiple threads, which
share the same resources but can run independently, so the thread is called as a lightweight process.
Multithreading
Multithreading refers to the ability to execute multiple threads concurrently within a single process.
Multithreading enhances the efficiency of multitasking by breaking down individual tasks into smaller
sub-tasks or threads. These threads can be processed simultaneously, making better use of the CPU’s
capabilities.
Advantages of Multithreading in Java
1. Improving performance and responsiveness.
2. Better Utilization of CPU
3. Time Saving
4. Achieve Tasking
The JVM can distribute threads across multiple cores, allowing true parallel execution of threads.
A thread is a lightweight process, the smallest unit of processing. Java supports multithreading through
its [Link] class and the [Link] interface.
Creating Threads in Java
Method 1: By extending the Thread class
Step 1: A new class World is created that extends Thread class.
Step 2: Override the run() method.
Step 3: create object for the new class
Step 4: call start() method to initiate the new thread, it automatically calls the run() method.
class thread1 {
public static void main(String[] args) {
World w1 = new World();
World w2 = new World();
[Link]();
[Link]();
for (int i=0;i<5;i++) {
[Link]("Hello");
}} }
class World extends Thread
{
public void run() {
for (int i=0;i<5;i++) {
[Link]("World");
}
}
}
output:
hello
hello
hello
world
world
world
world
world
world
world
hello
world
hello
world
world
Method 2: By implementing Runnable interface
Step 1: Create a new class that implements Runnable interface.
Step 2: Override the run() method.
Step 3: A Thread object is created by passing an instance of a new class.
Step 4 : call start() method initiate the new thread.
class thread1 {
public static void main(String[] args) {
World w = new World();
Thread t = new Thread(w);
[Link]();
for (int i=0;i<5;i++) {
[Link]("Hello");
}} }
class World implements Runnable
{
public void run() {
for (int i=0;i<5;i++) {
[Link]("World");
}
}
}
Thread Lifecycle
The lifecycle of a thread in Java consists of several states, which a thread can move through during its
execution.
They are:
1. New: In this state the thread is created but not yet started.
2. Runnable: After the start method is called, the thread becomes runnable. It’s ready to run and is
waiting for CPU time.
3. Running: In this the thread is in executing.
4. Blocked/Waiting: A thread is in this state when it is waiting for a resource or for another thread to
perform an action.
5. Terminated: A thread is in this state when it has finished executing.
Thread Class Methods
The [Link] class in Java provides numerous methods for creating, controlling, and managing threads.
Some of the commonly used methods are:
Thread Lifecycle Management:
start(): Begins the execution of a thread by calling its run() method.
run(): Contains the code that will be executed by the thread. This method is typically overridden when
extending Thread or implementing Runnable.
join(): Waits for a thread to die (complete its execution) before the current thread continues.
sleep(long millis): Causes the currently executing thread to pause for the specified number of
milliseconds.
interrupt(): Interrupts a thread, setting its interrupted status to true.
isAlive(): Checks if a thread is still active (has been started and has not yet died).
Thread Information and Manipulation:
getName(): Returns the name of the thread.
setName(String name): Sets the name of the thread.
getPriority(): Returns the priority of the thread.
setPriority(int newPriority): Sets the priority of the thread (values range
from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY).
getId(): Returns the unique identifier of the thread.
getState(): Returns the current state of the thread (e.g., NEW, RUNNABLE, BLOCKED, WAITING,
TIMED_WAITING, TERMINATED).
isDaemon(): Checks if the thread is a daemon thread.
setDaemon(boolean on): Marks the thread as a daemon thread. Daemon threads are background threads
that do not prevent the JVM from exiting.
Static Methods:
currentThread(): Returns a reference to the currently executing thread object.
yield(): Hints to the scheduler that the current thread is willing to yield its current use of a processor.
activeCount(): Returns an estimate of the number of active threads in the current thread's thread group.
dumpStack(): Prints a stack trace of the current thread to the standard error stream.
Synchronization and Inter-thread Communication (often used with Object methods):
wait(), wait(long timeout), wait(long timeout, int nanos): Causes the current thread to wait until
another thread invokes the notify() or notifyAll() method for this object, or a specified amount of time
has elapsed. These are methods of [Link].
notify(): Wakes up a single thread that is waiting on this object's monitor. This is a method
of [Link].
notifyAll(): Wakes up all threads that are waiting on this object's monitor. This is a method
of [Link].
Thread synchronization
Thread synchronization in Java is a mechanism used in multithreaded programming to control
access to shared resources and prevent data inconsistencies or race conditions. When multiple threads
attempt to access and modify the same data concurrently, the order of operations can become
unpredictable, leading to incorrect results. Synchronization ensures that only one thread can execute a
critical section of code (accessing a shared resource) at a time.
Importance of Thread Synchronization:
Prevents thread interference.
Prevents concurrency problems.
Thread synchronization is two types, they are:
[Link] Exclusive:
A Mutex or Mutual Exclusive helps only one thread to access the shared resources. It won’t allow the
accessing of shared resources at a time. It can be achieved in the following ways.
Synchronized Method
Synchronized block
Static Synchronization
Note: In java, we use synchronized keyword for the above methods.
Syntax: synchronized public void methodName() { }
2. Cooperation (Inter-Thread Communication in java)
Inter – Thread communication or cooperation is a communication of two or more threads with
each other. It can be done by using the following methods.
wait()
notify()
notifyAll()
Understanding the Problem without Synchronization
public class Table {
void printTable(int n) { // non synchronized method
for (int i = 1; i <= 5; i++) {
[Link](n * i);
try {
[Link](500);
} catch (InterruptedException ie) {
[Link](ie);
}
}
}
}
public class Thread1 extends Thread {
Table t; // Declaring t as class type table
// Declaring parameterized constructor and passing variable t as a parameter to the thread.
Thread1(Table t) {
this.t = t;
}
public void run() {
[Link](2);
}
}
public class Thread2 extends Thread {
Table t; // Declaring t as class type table
Thread2(Table t) {
this.t = t;
}
public void run() {
[Link](10);
}
}
public class UnsynchronizedMethod {
public static void main(String[] args) {
// Creating an object of Table class.
Table obj = new Table();
Thread1 t1 = new Thread1(obj);
Thread2 t2 = new Thread2(obj);
[Link]();
[Link]();
}
}
Output:
2
10
4
20
30
6
40
8
50
10
Example of Java Synchronization
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
[Link](n*i);
try{
[Link](400);
}catch(Exception e){[Link](e);}
}
}
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
[Link](2);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
[Link](10);
}
}
public class TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
[Link]();
[Link]();
}
}
Output:
2
4
6
8
10
20
30
40
50
60
Priority of a Thread in Java
Every Java thread has a priority that helps the operating system determine the order in
which threads are scheduled. You can get and set the priority of a Thread. Thread class provides methods
and constants for working with the priorities of a Thread.
Key aspects of thread priorities in Java:
Range:
Priorities are integers from Thread.MIN_PRIORITY (1)
to Thread.MAX_PRIORITY (10).
Default Priority:
All new threads are assigned Thread.NORM_PRIORITY (5) by default unless explicitly
set.
Setting Priority:
The setPriority(int newPriority) method of the Thread class is used to assign a priority to a
thread.
Getting Priority:
The getPriority() method of the Thread class returns the current priority of a thread.
Constants:
Java provides three static final constants in the Thread class for convenience:
Thread.MIN_PRIORITY (value 1)
Thread.NORM_PRIORITY (value 5)
Thread.MAX_PRIORITY (value 10)
Example Program1:
class MyThread extends Thread
{
public void run()
{
[Link]("Thread Running...");
}
public static void main(String[]args)
{
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
[Link]();
[Link](3);
[Link]("t1 thread priority : " + [Link]());
[Link]("t2 thread priority : " + [Link]());
[Link]("t3 thread priority : " + [Link]());
}
}
Output:
t1 thread priority : 5
Thread Running...
t2 thread priority : 3
t3 thread priority : 5
Example Program2:
class MyThread extends Thread
{
public void run()
{
[Link]("Thread Running...");
}
public static void main(String[]args)
{
MyThread t1 = new MyThread();
[Link]();
[Link]("max thread priority : " + t1.MAX_PRIORITY);
[Link]("min thread priority : " + t1.MIN_PRIORITY);
[Link]("normal thread priority : " + t1.NORM_PRIORITY);
}
}
Output:
Thread Running...
max thread priority : 10
min thread priority : 1
normal thread priority : 5