Skip to main content

11. Multithreading in Java

πŸ“ Multithreading in Java allows concurrent execution of two or more threads to maximize CPU utilization. It is a key feature for improving the performance of applications, especially in I/O-bound or CPU-bound tasks.

1. What is a Thread?​

  • A thread is a lightweight process, the smallest unit of processing that can be scheduled by the operating system.
  • Threads within the same process share resources like memory, while processes are independent and have their own memory space.

2. Creating Threads​

There are two primary ways to create threads in Java:

2.1. Extending the Thread Class​

You can create a thread by extending the Thread class and overriding its run() method.

class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread is running.");
}
}

// Usage
public class ThreadExample {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Start the thread
}
}

2.2. Implementing the Runnable Interface​

Alternatively, you can implement the Runnable interface, which allows you to define the run() method.

class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread is running.");
}
}

// Usage
public class RunnableExample {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // Start the thread
}
}

3. Thread Lifecycle​

A thread can be in one of the following states during its lifecycle:

  1. New: A thread that has been created but not yet started.
  2. Runnable: A thread that is ready to run and waiting for CPU time.
  3. Blocked: A thread that is waiting for a monitor lock to enter a synchronized block or method.
  4. Waiting: A thread that is waiting indefinitely for another thread to perform a particular action.
  5. Timed Waiting: A thread that is waiting for another thread to perform an action for a specified period.
  6. Terminated: A thread that has completed execution.

4. Thread Synchronization​

To prevent thread interference when multiple threads access shared resources, synchronization is essential. This can be achieved using:

4.1. Synchronized Methods​

You can declare a method as synchronized to restrict access to it by multiple threads.

public synchronized void synchronizedMethod() {
// Code to be executed by only one thread at a time
}

4.2. Synchronized Blocks​

You can also synchronize a block of code to allow finer control over synchronization.

public void someMethod() {
synchronized (this) {
// Code to be executed by only one thread at a time
}
}

5. Inter-Thread Communication​

Threads can communicate with each other using methods like wait(), notify(), and notifyAll(), which are defined in the Object class.

Example:​

public class CommunicationExample {
private static final Object lock = new Object();

public void producer() {
synchronized (lock) {
// Produce an item and notify waiting consumers
lock.notify();
}
}

public void consumer() {
synchronized (lock) {
try {
// Wait for an item to be produced
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

6. Thread Priority​

Threads in Java have a priority that helps the thread scheduler determine the order of thread execution. The priority can be set using the setPriority(int priority) method.

  • Priority Levels: Ranges from Thread.MIN_PRIORITY (1) to Thread.MAX_PRIORITY (10), with Thread.NORM_PRIORITY (5) as the default.
Thread thread = new Thread(new MyRunnable());
thread.setPriority(Thread.MAX_PRIORITY);

7. Executor Framework​

Java provides the Executor framework to manage thread pools more efficiently, avoiding the overhead of thread creation and destruction.

Example:​

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);

executor.submit(() -> {
System.out.println("Task 1 is running");
});

executor.submit(() -> {
System.out.println("Task 2 is running");
});

executor.shutdown(); // Shutdown the executor
}
}

Summary of Multithreading Concepts​

ConceptDescription
ThreadLightweight process for concurrent execution.
Creating ThreadsExtend Thread class or implement Runnable interface.
Thread LifecycleNew, Runnable, Blocked, Waiting, Timed Waiting, Terminated.
SynchronizationPrevents thread interference using synchronized methods and blocks.
Inter-Thread CommunicationCommunication using wait(), notify(), and notifyAll().
Thread PriorityDetermines the order of thread execution (1-10).
Executor FrameworkManages thread pools for efficient execution.

This overview provides a foundational understanding of multithreading in Java.