0% found this document useful (0 votes)
4 views

Multithreading in Java

The document provides an overview of multithreading in Java, including definitions, advantages, and key concepts such as thread lifecycle and synchronization. It explains how to create threads using the Thread class and Runnable interface, and discusses thread methods, deadlock prevention, and advanced concepts like thread pools and Callable. Additionally, it covers synchronization utilities like CountDownLatch and CyclicBarrier for managing thread interactions.

Uploaded by

Jha Avinash
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Multithreading in Java

The document provides an overview of multithreading in Java, including definitions, advantages, and key concepts such as thread lifecycle and synchronization. It explains how to create threads using the Thread class and Runnable interface, and discusses thread methods, deadlock prevention, and advanced concepts like thread pools and Callable. Additionally, it covers synchronization utilities like CountDownLatch and CyclicBarrier for managing thread interactions.

Uploaded by

Jha Avinash
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

‭1.

Introduction to Multithreading in Java‬

‭●‬ D ‭ efinition‬‭: Multithreading is a process of executing‬‭two or more threads‬


‭simultaneously for maximum CPU utilization. A thread is the smallest unit of a‬
‭process, and multiple threads within a process share the same memory space.‬
‭●‬ ‭Advantages‬‭:‬
‭○‬ ‭Efficient utilization of CPU.‬
‭○‬ ‭Better performance in tasks involving I/O operations.‬
‭○‬ ‭Simplified modeling of complex, asynchronous processes.‬
‭○‬ ‭Reduces idle time (e.g., waiting for I/O).‬
‭●‬ ‭Key Concepts‬‭:‬
‭○‬ ‭Thread‬‭: A lightweight sub-process.‬
‭○‬ ‭Process vs. Thread‬‭:‬
‭■‬ ‭A process has its own memory space, while threads share memory‬
‭within the same process.‬
‭○‬ ‭Concurrency vs. Parallelism‬‭:‬
‭■‬ ‭Concurrency: Multiple tasks start, run, and complete in overlapping‬
‭time periods.‬
‭■‬ ‭Parallelism: Tasks run simultaneously on multiple CPUs.‬

‭2. Creating Threads in Java‬

‭Java provides two ways to create a thread:‬

‭A. Extending the‬‭


Thread‬‭Class‬
‭Java code‬
class MyThread extends Thread {‬

@Override‬

public void run() {‬

‭System.out.println("Thread is running: " +‬
Thread.currentThread().getName());‬

}‬

}‬

public class ThreadExample {‬



public static void main(String[] args) {‬

‭MyThread thread = new MyThread();‬
‭thread.start(); // Start the thread‬
}‬

}‬

‭B. Implementing the‬‭
Runnable‬‭Interface‬
‭Java code‬
class MyRunnable implements Runnable {‬

@Override‬

public void run() {‬

‭System.out.println("Thread is running: " +‬
Thread.currentThread().getName());‬

}‬

}‬

public class ThreadExample {‬



public static void main(String[] args) {‬

‭Thread thread = new Thread(new MyRunnable());‬
‭thread.start(); // Start the thread‬
}‬

}‬

‭Key Points:‬

‭●‬ ‭Use‬‭
Thread‬‭class when you don’t need to extend any‬‭other class.‬
‭ se‬‭
‭●‬ U Runnable‬‭when the class needs to extend another‬‭class, as Java does not‬
‭support multiple inheritance.‬

‭3. Thread Lifecycle‬

‭A thread in Java has the following states:‬

‭1.‬ ‭New‬‭: Created but not started.‬


‭○‬ ‭Created using‬‭ Thread t = new Thread();‬ ‭.‬
‭2.‬ ‭Runnable‬‭: Ready to run but waiting for the CPU.‬
‭○‬ ‭After calling‬‭
start()‬‭.‬
‭3.‬ ‭Running‬‭: Currently executing.‬
‭○‬ ‭Scheduled by the JVM thread scheduler.‬
‭4.‬ ‭Blocked/Waiting‬‭: Waiting for resources or another‬‭thread.‬
‭5.‬ ‭Terminated‬‭: Completed execution.‬

‭Example: Thread Lifecycle‬


‭Java code‬
class MyThread extends Thread {‬

@Override‬

public void run() {‬

‭try {‬
S‭ystem.out.println("Thread is running");‬
‭Thread.sleep(1000); // Puts thread in a timed waiting‬
state‬

‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭}‬
‭System.out.println("Thread is finished");‬
}‬

}‬

public class ThreadLifecycle {‬



public static void main(String[] args) {‬

‭Thread t = new MyThread();‬
‭System.out.println("Thread State: " + t.getState()); // NEW‬
‭t.start();‬
‭System.out.println("Thread State: " + t.getState()); //‬
RUNNABLE‬

}‬

}‬

‭4. Thread Methods‬


‭Method‬ ‭Description‬

start()‬
‭ ‭Starts the thread.‬

run()‬
‭ ‭Entry point for thread execution.‬

sleep(milliseconds)‬ ‭Causes the thread to pause for a specified time.‬


join()‬
‭ ‭Waits for a thread to finish execution before continuing.‬

getName()‬
‭ ‭Returns the thread's name.‬

‭etName(String‬
s ‭Sets the thread's name.‬
name)‬

‭etPriority(int‬
s ‭Sets the thread priority (1 to 10).‬
value)‬

isAlive()‬
‭ ‭Returns‬‭
true‬‭if the thread is still running.‬

interrupt()‬
‭ ‭Interrupts the thread if it is sleeping or waiting.‬
‭Example:‬‭
join()‬‭and‬‭
sleep()‬
‭Java code‬
class MyThread extends Thread {‬

@Override‬

public void run() {‬

‭for (int i = 0; i < 5; i++) {‬
‭System.out.println("Thread: " + i);‬
‭try {‬
‭Thread.sleep(500); // Pause for 500ms‬
‭} catch (InterruptedException e) {‬
‭System.out.println("Thread interrupted");‬
‭}‬
‭}‬
}‬

}‬

public class ThreadMethods {‬



public static void main(String[] args) {‬

‭MyThread thread = new MyThread();‬
‭thread.start();‬
‭try {‬
‭thread.join(); // Wait for thread to finish‬
‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭}‬
‭System.out.println("Main thread finished");‬
}‬

}‬

‭5. Thread Synchronization‬

‭ hen multiple threads access shared resources, synchronization is needed to prevent data‬
W
‭inconsistency.‬

‭Synchronization Using‬‭
synchronized‬‭Keyword‬
‭ ynchronized Method‬‭:‬
S
‭Java code‬
class SharedResource {‬

synchronized void printNumbers(int n) {‬

‭for (int i = 1; i <= 5; i++) {‬
‭System.out.println(n * i);‬
‭try {‬
‭Thread.sleep(400);‬
‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭}‬
‭}‬
}‬

}‬

class MyThread extends Thread {‬



SharedResource resource;‬

MyThread(SharedResource resource) {‬

‭this.resource = resource;‬
}‬

‭Override‬
@
public void run() {‬

‭resource.printNumbers(5);‬
}‬

}‬

public class SynchronizedExample {‬



public static void main(String[] args) {‬

‭SharedResource resource = new SharedResource();‬
‭MyThread t1 = new MyThread(resource);‬
‭MyThread t2 = new MyThread(resource);‬
‭t1.start();‬
‭t2.start();‬
}‬

}‬

‭ ynchronized Block‬‭:‬
S
‭Java code‬
synchronized (object) {‬

// Critical section‬

}‬

‭6. Deadlock and Its Prevention‬

‭●‬ D
‭ eadlock‬‭: Occurs when two or more threads are blocked forever, waiting for each‬
‭other’s resources.‬

‭Example of Deadlock‬
‭Java code‬
‭lass Resource1 {}‬
c
class Resource2 {}‬

public class DeadlockExample {‬



public static void main(String[] args) {‬

‭Resource1 r1 = new Resource1();‬
‭Resource2 r2 = new Resource2();‬

‭Thread t1 = new Thread(() -> {‬


‭synchronized (r1) {‬
‭System.out.println("Thread 1: Locked Resource 1");‬
‭try { Thread.sleep(100); } catch (Exception e) {}‬
‭synchronized (r2) {‬
‭System.out.println("Thread 1: Locked Resource‬
2");‬

‭}‬
}‭‬
‭});‬

‭Thread t2 = new Thread(() -> {‬


‭synchronized (r2) {‬
‭System.out.println("Thread 2: Locked Resource 2");‬
‭try { Thread.sleep(100); } catch (Exception e) {}‬
‭synchronized (r1) {‬
‭System.out.println("Thread 2: Locked Resource‬
1");‬

‭}‬
}‭‬
‭});‬

t‭1.start();‬
‭t2.start();‬
}‬

}‬

‭Deadlock Prevention Strategies:‬

‭‬ U
● ‭ se a consistent lock order.‬
‭●‬ ‭Avoid nested locks.‬
‭●‬ ‭Use‬‭tryLock‬‭from‬‭java.util.concurrent.locks‬‭.‬

‭7. Advanced Multithreading Concepts‬

‭Let’s now explore more advanced concepts in multithreading:‬

‭7.1. Thread Pools‬

‭●‬ A ‭ ‬‭Thread Pool‬‭manages a fixed number of threads, reducing‬‭the overhead of‬


‭creating and destroying threads repeatedly.‬
‭●‬ ‭Used when we have multiple tasks to execute but limited threads to manage them‬
‭efficiently.‬

‭Creating a Thread Pool‬

‭ ava provides‬‭
J ExecutorService‬‭in the‬‭
java.util.concurrent‬‭package to manage‬
‭thread pools.‬

‭Java code‬
‭mport java.util.concurrent.ExecutorService;‬
i
import java.util.concurrent.Executors;‬

public class ThreadPoolExample {‬



public static void main(String[] args) {‬

‭ExecutorService executor = Executors.newFixedThreadPool(3);‬
// Pool of 3 threads‬

‭for (int i = 1; i <= 5; i++) {‬


‭final int taskNumber = i;‬
‭executor.execute(() -> {‬
‭System.out.println("Executing Task " + taskNumber +‬
" by " + Thread.currentThread().getName());‬

‭try {‬
‭Thread.sleep(500); // Simulate task execution‬
‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭}‬
‭});‬
‭}‬

e‭xecutor.shutdown(); // Shutdown the executor after tasks‬


completion‬

}‬

}‬

‭Common Thread Pool Types:‬

‭1.‬ ‭Fixed Thread Pool‬‭:‬‭ Executors.newFixedThreadPool(n)‬


‭○‬ ‭Predefined number of threads.‬
‭2.‬ ‭Cached Thread Pool‬‭:‬‭ Executors.newCachedThreadPool()‬
‭○‬ ‭Creates new threads as needed and reuses existing threads.‬
‭3.‬ ‭Single Thread Executor‬‭:‬‭ Executors.newSingleThreadExecutor()‬
‭○‬ ‭Only one thread for task execution.‬
‭4.‬ ‭Scheduled Thread Pool‬‭:‬‭ Executors.newScheduledThreadPool(n)‬
‭○‬ ‭Executes tasks with a delay or periodically.‬

‭7.2. Callable and Future‬

Runnable‬‭does not return a result, but‬‭


‭ Callable‬‭can.‬

‭Callable Example‬
‭Java code‬
‭mport
i java.util.concurrent.Callable;‬
import
‭ java.util.concurrent.ExecutorService;‬
import
‭ java.util.concurrent.Executors;‬
import
‭ java.util.concurrent.Future;‬

public class CallableExample {‬



public static void main(String[] args) {‬

‭ExecutorService executor =‬
Executors.newSingleThreadExecutor();‬

‭Callable<Integer> task = () -> {‬


‭System.out.println("Performing a computation in " +‬
Thread.currentThread().getName());‬

‭Thread.sleep(1000); // Simulate computation‬
‭return 42; // Return a result‬
‭};‬
‭Future<Integer> future = executor.submit(task);‬

‭try {‬
‭System.out.println("Waiting for the result...");‬
‭Integer result = future.get(); // Blocks until the‬
result is available‬

‭System.out.println("Result: " + result);‬
‭} catch (Exception e) {‬
‭e.printStackTrace();‬
‭}‬

‭executor.shutdown();‬
}‬

}‬

‭Key Points:‬

‭‬ C
● ‭ allable‬‭: Similar to‬‭
Runnable‬‭but returns a result‬‭and can throw exceptions.‬
‭●‬ ‭Future‬‭: Represents the result of an asynchronous computation.‬

‭7.3. Synchronization Utilities‬

‭ ava provides synchronization utilities in the‬‭


J java.util.concurrent‬‭package to manage‬
‭thread interactions.‬

‭CountDownLatch‬

‭Used to make one thread wait for others to complete.‬

‭Java code‬
import java.util.concurrent.CountDownLatch;‬

public class CountDownLatchExample {‬



public static void main(String[] args) {‬

‭CountDownLatch latch = new CountDownLatch(3); // Wait for 3‬
threads‬

‭for (int i = 1; i <= 3; i++) {‬


‭new Thread(() -> {‬
‭System.out.println(Thread.currentThread().getName()‬
+ " finished work");‬

‭latch.countDown(); // Decrement the count‬
‭}).start();‬
‭}‬

‭try {‬
‭latch.await(); // Wait until count reaches 0‬
‭System.out.println("All threads have finished.‬
Proceeding...");‬

‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭}‬
}‬

}‬

‭CyclicBarrier‬

‭Used to make threads wait for each other at a common barrier point.‬

‭Java code‬
import java.util.concurrent.CyclicBarrier;‬

public class CyclicBarrierExample {‬



public static void main(String[] args) {‬

‭CyclicBarrier barrier = new CyclicBarrier(3, () -> {‬
‭System.out.println("All threads have reached the‬
barrier. Proceeding...");‬

‭});‬

‭for (int i = 1; i <= 3; i++) {‬


‭new Thread(() -> {‬
‭try {‬

‭ystem.out.println(Thread.currentThread().getName() + " waiting at‬


S
the barrier");‬

‭barrier.await(); // Wait for others to reach‬
‭} catch (Exception e) {‬
‭e.printStackTrace();‬
‭}‬
‭}).start();‬
‭}‬
}‬

}‬

‭7.4. Locks‬

ReentrantLock‬‭is an alternative to synchronized blocks/methods,‬‭offering more flexibility.‬


‭ReentrantLock Example‬
‭Java code‬
‭mport java.util.concurrent.locks.Lock;‬
i
import java.util.concurrent.locks.ReentrantLock;‬

public class ReentrantLockExample {‬



private final Lock lock = new ReentrantLock();‬

public void printNumbers() {‬



‭lock.lock(); // Acquire the lock‬
‭try {‬
‭for (int i = 1; i <= 5; i++) {‬
‭System.out.println(Thread.currentThread().getName()‬
+ " - " + i);‬

‭Thread.sleep(500);‬
‭}‬
‭} catch (InterruptedException e) {‬
‭e.printStackTrace();‬
‭} finally {‬
‭lock.unlock(); // Release the lock‬
‭}‬
}‬

public static void main(String[] args) {‬



‭ReentrantLockExample example = new ReentrantLockExample();‬

T‭hread t1 = new Thread(example::printNumbers);‬


‭Thread t2 = new Thread(example::printNumbers);‬

t‭1.start();‬
‭t2.start();‬
}‬

}‬

‭Key Points:‬

‭●‬ ‭ock.lock()‬
l ‭: Acquires the lock.‬
‭‬ ‭
● lock.unlock()‬ ‭: Releases the lock.‬
‭●‬ ‭Use‬‭
try-finally‬‭to ensure proper release of locks.‬

‭7.5. Fork/Join Framework‬

‭ he Fork/Join framework is designed for parallel execution of tasks. It splits a task into‬
T
‭subtasks (fork) and merges the results (join).‬

‭Example‬
‭Java code‬
‭mport java.util.concurrent.RecursiveTask;‬
i
import java.util.concurrent.ForkJoinPool;‬

class SumTask extends RecursiveTask<Integer> {‬



private final int[] arr;‬

private final int start, end;‬

public SumTask(int[] arr, int start, int end) {‬



‭this.arr = arr;‬
‭this.start = start;‬
‭this.end = end;‬
}‬

‭Override‬
@
protected Integer compute() {‬

‭if (end - start <= 2) { // Small enough to compute directly‬
‭int sum = 0;‬
‭for (int i = start; i < end; i++) {‬
‭sum += arr[i];‬
‭}‬
‭return sum;‬
‭} else {‬
‭int mid = (start + end) / 2;‬
‭SumTask task1 = new SumTask(arr, start, mid);‬
‭SumTask task2 = new SumTask(arr, mid, end);‬

‭task1.fork(); // Split task1‬


‭return task2.compute() + task1.join(); // Combine‬
results‬

‭}‬
}‬

}‬

public class ForkJoinExample {‬



public static void main(String[] args) {‬

‭ForkJoinPool pool = new ForkJoinPool();‬
‭int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};‬

S‭umTask task = new SumTask(arr, 0, arr.length);‬


‭int result = pool.invoke(task);‬

‭System.out.println("Sum: " + result);‬


}‬

}‬

‭Frequently Asked Java Multithreading Interview Questions‬

‭Basics‬

‭ .‬
1 ‭ hat is a thread, and how is it different from a process?‬
W
‭2.‬ ‭What are the main states of a thread in Java?‬
‭3.‬ ‭Explain the differences between‬‭Runnable‬‭and‬‭ Thread‬‭classes.‬
‭4.‬ ‭How do you create a thread in Java? Which approach is preferred and why?‬

‭Thread Lifecycle and Methods‬

‭ .‬ E
5 ‭ xplain the lifecycle of a thread with an example.‬
‭6.‬ ‭What is the purpose of the‬‭ join()‬‭method in Java?‬‭Provide an example.‬
‭7.‬ ‭What does the‬‭
sleep()‬‭method do? How is it different‬‭from‬‭
wait()‬‭?‬
‭8.‬ ‭What is‬‭
Thread.yield()‬‭and when should it be used?‬

‭Thread Synchronization‬

‭ .‬ ‭Why is thread synchronization needed? Explain with an example.‬


9
‭10.‬‭What is the difference between synchronized methods and synchronized blocks?‬
‭11.‬‭What is a deadlock? How can you prevent it in multithreading?‬
‭12.‬‭Explain thread-safe classes and provide examples.‬
‭Advanced Concepts‬

‭ 3.‬‭What is a thread pool? Why should you use it?‬


1
‭14.‬‭Explain the difference between‬‭
Callable‬‭and‬‭ Runnable‬
‭.‬
‭15.‬‭What is the purpose of the‬‭
Future‬‭interface?‬
‭16.‬‭What is‬‭
ReentrantLock‬‭and how is it different from‬‭
synchronized‬‭?‬
‭17.‬‭How does the‬‭
CountDownLatch‬‭work? When should you use it?‬

‭Concurrency Utilities‬

‭18.‬‭What is the difference between‬‭


CyclicBarrier‬‭and‬‭
CountDownLatch‬
‭?‬
‭ 9.‬‭Explain‬‭
1 Fork/Join‬‭framework with a simple use case.‬
‭20.‬‭What are concurrent collections in Java? Provide examples (e.g.,‬
ConcurrentHashMap‬
‭ ‭,‬‭
CopyOnWriteArrayList‬ ‭).‬

‭Common Problems‬

‭ 1.‬‭What is race condition? How can it be avoided in Java?‬


2
‭22.‬‭What happens if you call‬‭
start()‬‭twice on the same‬‭thread?‬
‭ 3.‬‭How can you stop a thread in Java? Why is‬‭
2 Thread.stop()‬‭deprecated?‬
‭24.‬‭How do you handle exceptions in multithreading?‬

You might also like