Java Multithreading
• Multithreading in Java is a feature that allows multiple tasks to run
concurrently within the same program.
• Instead of executing one task at a time, Java enables parallel execution
using lightweight threads.
• This makes applications more efficient, faster and responsive in real-
world scenarios like servers, games and chat systems.
• It improves application performance and responsiveness.
• To achieve the multithreading (or, write multithreaded code), you
need [Link] class.
Key Features of Multithreading
• A thread is the smallest unit of execution in Java.
• Threads share the same memory space but run independently.
• Java provides the Thread class and Runnable interface to create
threads.
• Multithreading ensures better CPU utilization by executing tasks
simultaneously.
• Synchronization is needed to prevent data inconsistency when threads
share resources.
Advantages of Multithreading in Java
• Improved Performance: Multiple tasks can run simultaneously,
reducing execution time.
• Efficient CPU Utilization: Threads keep the CPU busy by running
tasks in parallel.
• Responsiveness: Applications (like GUIs) remain responsive while
performing background tasks.
• Resource Sharing: Threads within the same process share memory
and resources, avoiding duplication.
• Better User Experience: Smooth execution of tasks like file
downloads, animations, and real-time updates.
Life Cycle of a Thread in Java Multithreading
• A thread goes through various stages in its life cycle.
• For example, a thread is born, started, runs, and then dies.
Stages of the life cycle
• New − A new thread begins its life cycle in the new state. It remains in this
state until the program starts the thread. It is also referred to as a born thread.
• Runnable − After a newly born thread is started, the thread becomes runnable.
A thread in this state is considered to be executing its task.
• Waiting − Sometimes, a thread transitions to the waiting state while the thread
waits for another thread to perform a task. A thread transitions back to the
runnable state only when another thread signals the waiting thread to continue
executing.
• Timed Waiting − A runnable thread can enter the timed waiting state for a
specified interval of time. A thread in this state transitions back to the runnable
state when that time interval expires or when the event it is waiting for occurs.
• Terminated (Dead) − A runnable thread enters the terminated state when it
completes its task or otherwise terminates.
Creating a Thread
There are two ways to create a thread.
1. Create a Thread by Extending a Thread Class
• It can be created by extending the Thread class and overriding
its run() method:
[Link] a Thread by Implementing the Runnable Interface
Running Threads
• If the class extends the Thread class, the thread can be run by
creating an instance of the class and call its start() method
Implement Example
• If the class implements the Runnable interface, the thread can be run
by passing an instance of the class to a Thread object's constructor and
then calling the thread's start() method.
// Extend the Thread class class ThreadExample {
class MyThread extends Thread { public static void main(String[] args) {
public void run() { MyThread t1 = new MyThread();
[Link]("Thread is [Link]();
running: " + [Link]("Main thread: " +
[Link]().getName()); [Link]().getName());
for (int i = 1; i <= 5; i++) { }
[Link]("Count " + i + " }
from " + OUTPUT:
[Link]().getName()); Main thread: main
try { Thread is running: Thread-0
[Link](500); Count 1 from Thread-0
} catch (InterruptedException e) { Count 2 from Thread-0
[Link]("Thread Count 3 from Thread-0
interrupted"); Count 4 from Thread-0
} Count 5 from Thread-0
}}}
// Class implements Runnable interface public class RunnableExample {
class MyRunnable implements Runnable { public static void main(String[] args) {
public void run() { MyRunnable myRunnable = new
MyRunnable(); // Create Runnable object
[Link]("Thread is running: " +
[Link]().getName()); Thread thread = new Thread(myRunnable);
for (int i = 1; i <= 5; i++) { [Link]();
[Link]("Count " + i + " from [Link]("Main thread: " +
" + [Link]().getName()); [Link]().getName());
try { }}
OUTPUT
[Link](500); // Sleep for 500
milliseconds Main thread: main
} catch (InterruptedException e) { Thread is running: Thread-0
[Link]("Thread Count 1 from Thread-0
interrupted"); Count 2 from Thread-0
}} Count 3 from Thread-0
}} Count 4 from Thread-0
Count 5 from Thread-0
Commonly Used Methods of Thread Class
1. Thread Information & Control
• getName() → returns the thread’s name.
• setName(String name) → sets the thread’s name.
• getId() → returns the thread’s unique ID.
• getPriority() → returns thread’s priority (1–10).
• setPriority(int newPriority) → sets thread’s priority.
• getState() → returns the state of the thread (NEW, RUNNABLE, WAITING, etc.).
• isAlive() → checks if thread is still running.
• isDaemon() → checks if thread is daemon.
• setDaemon(boolean b) → marks thread as daemon (must be called before start()).
[Link] Execution
• start() → starts execution of the thread (calls run() internally).
• run() → contains the code that thread executes (override this).
• join() → waits for a thread to finish.
• join(long millis) → waits for given time or until thread finishes.
• sleep(long millis) → makes the current thread pause for specified time.
• yield() → hints to the scheduler to give other threads a chance.
• interrupt() → interrupts a thread (if it’s sleeping/waiting).
• isInterrupted() → checks if thread has been interrupted.
• interrupted() (static) → checks & clears interrupt status of current
thread.
[Link] Groups & Management
• activeCount() (static) → returns number of active threads in current
group.
• enumerate(Thread[] tarray) → copies active threads into an array.
• currentThread() (static) → returns reference to currently running
thread.
4. Deprecated / Less Commonly Used
• stop() (deprecated) → forcibly stops a thread (unsafe).
• suspend() / resume() (deprecated) → pause/resume a thread (unsafe).
When to Use Which?
• Use extends Thread: if your class does not extend any other class.
• Use implements Runnable: if your class already extends another
class (preferred because Java doesn’t support multiple inheritance).
class MyThread extends Thread { // Display thread details
public void run() { [Link]("Thread Name: " +
[Link]());
[Link]("Thread is running: " +
getName()); [Link]("Thread ID: " + [Link]())
} [Link]("Thread Priority: " +
[Link]());
}
[Link]("Is Daemon: " +
public class ThreadMethodsDemo { [Link]());
public static void main(String[] args) { // Start the thread
MyThread t1 = new MyThread(); [Link]();
// Set name and priority }
[Link]("Worker-1"); }OUTPUT
Thread Name: Worker-1
[Link](Thread.MAX_PRIORITY); // Thread ID: 11
Priority = 10 Thread Priority: 10
Is Daemon: false
Thread is running: Worker-1
Thread Priorities
• The thread scheduler assigns the processor to a thread based on the
priority of the thread.
• Whenever a thread is created, it always has some priority assigned to
it.
• Priority can either be given by JVM while creating the thread or it can
be given by the programmer explicitly.
• Priority for a thread is represented by numbers ranging from 1 to 10
Built-in Property Constants of Thread Class
Java thread priorities are in the range between MIN_PRIORITY (a
constant of 1) and MAX_PRIORITY (a constant of 10).
By default, every thread is given priority NORM_PRIORITY (a
constant of 5).
• MIN_PRIORITY: Specifies the minimum priority that a thread can
have.
• NORM_PRIORITY: Specifies the default priority that a thread is
assigned.
• MAX_PRIORITY: Specifies the maximum priority that a thread can
have.
Thread Priority Setter and Getter Methods
• [Link]() Method: This method is used to get the priority
of a thread.
• [Link]() Method: This method is used to set the priority
of a thread, it accepts the priority value and updates an existing
priority with the given priority.
class MyThread extends Thread { [Link](Thread.MAX_PRIORITY);
public void run() { // Display priorities before starting
[Link]("Thread is running: " +
getName() +" with priority: " + getPriority()); [Link]([Link]() + "
Priority: " + [Link]());
}}
public class ThreadPriorityExample { [Link]([Link]() + "
Priority: " + [Link]());
public static void main(String[] args)
{ // Create three thread [Link]([Link]() + "
Priority: " + [Link]());
MyThread t1 = new MyThread();
// Start threads
MyThread t2 = new MyThread();
MyThread t3 = new MyThread(); [Link]();
[Link]("Worker-1"); [Link]();
[Link]("Worker-2");
[Link]();
[Link]("Worker-3");
}
[Link](Thread.MIN_PRIORITY); // 1
[Link](Thread.NORM_PRIORITY); // 5 }
Synchronization of Thread
• Thread synchronization in Java is a mechanism used to control access to
shared resources by multiple threads, preventing data inconsistency and
race conditions.
• This ensures that only one thread can access a critical section (a block of
code or shared resource) at a time.
• Thread synchronization refers to The concept of one thread execute at a
time and the rest of the threads are in waiting state. This process is
known as thread synchronization.
• when a thread request a resource then that resource gets locked so that
no other thread can work or do any modification until the resource gets
released.
Importance of Thread Synchronization
• In a multithreaded environment, threads may compete for shared
resources i.e. files, memory, etc.
Without synchronization, simultaneous access can lead
• Race Conditions: Multiple Threads interchanging shared data at the
same time and it results an unpredictable output.
• Data Corruption: Incomplete or corrupted data when multiple
threads modify the same resource simultaneously.
Types of Synchronization
There are two type of synchronizations in Java
• Process Synchronization-Process Synchronization is a technique
used to coordinate the execution of multiple processes. It ensures
that the shared resources are safe and in order.
• Thread Synchronization-Thread Synchronization is used to
coordinate and ordering of the execution of the threads in a multi-
threaded program.
There are two types of thread synchronization
• Mutual Exclusive
• Cooperation (Inter-thread communication in Java)
Mutual Exclusion
Ensures that only one thread can access a critical section (shared
resource) at a time, preventing race conditions and data inconsistency.
Java provides the following mechanisms for mutual exclusion:
• Synchronized Methods: Marking a method with the synchronized
keyword locks the object on which the method is invoked, allowing
only one thread to execute any synchronized method of that object at a
time.
• Synchronized Blocks: Using a synchronized block allows for finer-
grained control by specifying a specific object to be locked, enabling
synchronization over a smaller portion of code.
Cooperation (Inter-thread Communication)
• This allows threads to communicate and coordinate their actions,
enabling them to wait for certain conditions to be met or to signal other
threads. Java provides the following methods for inter-thread
communication, which are part of the Object class:
• wait(): Causes the current thread to wait until another thread invokes the
notify() or notifyAll() method for this object.
• notify(): Wakes up a single thread that is waiting on this object's
monitor.
• notifyAll(): Wakes up all threads that are waiting on this object's
monitor.
Synchronization - Method
class MyThread extends Thread
{
public synchronized void run()
{
for (int i = 1; i <=3; i++)
{
[Link]([Link]().getName() + “assignment " + i);
try
{
[Link](100); // just to slow down
}
catch (Exception e)
{
[Link](e);
} } }}
Synchronization - Method
public class Main
{
public static void main(String[] args)
{
MyThread task = new MyThread();// shared object
Thread s1 = new Thread(task, "subject-1");
Thread s2 = new Thread(task, "subject-2");
[Link]();
[Link]();
}}
OUTPUT
subject-1 assignment 1
subject-1 assignment 2
subject-1 assignment 3
subject-2 assignment 1
subject-2 assignment 2
subject-2 assignment 3
Synchronized Block
class MyThread extends Thread
{
public void run()
{
[Link]([Link]().getName() + "welcomes");
synchronized(this)
{
for (int i = 1; i <=3; i++)
{
[Link]([Link]().getName() + " assignment " + i);
try
{
[Link](1000);
}
catch (Exception e)
{
[Link](e);
} } } }}
public class Main
{
public static void main(String[] args)
{
MyThread task = new MyThread(); // shared object
Thread s1 = new Thread(task, "subject-1");
Thread s2 = new Thread(task, "subject-2");
[Link]();
[Link]();
}}
OUTPUT
subject-1 welcomes
subject-1 assignment 1
subject-1 assignment 2
subject-1 assignment 3
subject-2 welcomes
subject-2 assignment 1
subject-2 assignment 2
subject-2 assignment 3
Inter-Thread Communication
Inter-Thread Communication or Co-operation is all about
allowing synchronized threads to communicate with each other.
It is implemented by following methods of Object class and all
these methods can be called only from within a synchronized
context.
•public final void wait() throws InterruptedException
•public final void wait(long timeout) throws
InterruptedException
•public final void notify()
•Public final void notifyAll()
Example
class ThreadB extends Thread
{
int total=0;
public void run()
{
synchronized(this)
{
for(int i=1;i<=10;i++)
{
total+=i;
}
[Link]();
} }}
public class ThreadA
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
[Link]();
synchronized(b)
{
try
{
[Link]();
[Link]([Link]);
}
catch(Exception e)
OUTPUT: 55
{
[Link](e); } } }}
Suspending, Resuming and stopping threads
• Suspending a thread essentially means halting its execution
temporarily.
• Resuming threads: allowing suspended thread for execution.
• Stopping threads: make the thread to finish its work. Avoid
forcing a thread to stop directly .
class thread1 extends Thread
{
public void run()
{
for(int i=0;i<3;i++)
{
try
{
[Link]([Link]().getName()+" executing\t i="+i);
sleep(2000);
}
catch(Exception e)
{
[Link](e);
}}}}
class sample [Link]();
{ [Link]();
public static void main(String args[]) [Link]();
{ [Link]();
thread1 t0=new thread1(); [Link]();
thread1 t1=new thread1(); [Link]();
thread1 t2=new thread1(); [Link]();
thread1 t3=new thread1(); [Link]();
thread1 t4=new thread1(); [Link]();
thread1 t5=new thread1(); [Link]();
thread1 t6=new thread1(); }
}
Wrapper classes
• Wrapper classes are a set of classes that allow primitive data
types (such as int, char, boolean, etc.) to be treated as objects.
These classes are part of the [Link] package .
• Primitive types (e.g., int, char, double) are not objects and
therefore cannot be used in places that require objects. To
overcome this problem wrapper classes are used.
List of Wrapper Classes
Autoboxing
• Autoboxing is automatically converting a primitive to its
corresponding wrapper class when necessary.
• Unboxing is automatically converting a wrapper class back to a
primitive when needed.
Example
public class WrapperExample
{
public static void main(String[] args)
{
int a=10;
Integer intObj = a;//Autoboxing
int num = intObj;// unboxing
[Link]("Integer Object: " + intObj);
[Link]("Primitive int: " + num);
}
}