1.
Introduction to Multithreading in Java
● D efinition: Multithreading is a process of executingtwo 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
ThreadClass
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
RunnableInterface
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
Threadclass when you don’t need to extend anyother class.
se
● U Runnablewhen the class needs to extend anotherclass, 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 anotherthread.
5. Terminated: Completed execution.
Example: Thread Lifecycle
Java code
class MyThread extends Thread {
@Override
public void run() {
try {
System.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
trueif 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
synchronizedKeyword
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");
}
}
});
t1.start();
t2.start();
}
}
Deadlock Prevention Strategies:
U
● se a consistent lock order.
● Avoid nested locks.
● UsetryLockfromjava.util.concurrent.locks.
7. Advanced Multithreading Concepts
Let’s now explore more advanced concepts in multithreading:
7.1. Thread Pools
● A Thread Poolmanages a fixed number of threads, reducingthe 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 ExecutorServicein the
java.util.concurrentpackage 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();
}
});
}
executor.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
Runnabledoes not return a result, but
Callablecan.
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
Runnablebut returns a resultand can throw exceptions.
● Future: Represents the result of an asynchronous computation.
7.3. Synchronization Utilities
ava provides synchronization utilities in the
J java.util.concurrentpackage 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
ReentrantLockis 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();
Thread t1 = new Thread(example::printNumbers);
Thread t2 = new Thread(example::printNumbers);
t1.start();
t2.start();
}
}
Key Points:
● ock.lock()
l : Acquires the lock.
● lock.unlock() : Releases the lock.
● Use
try-finallyto 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};
SumTask 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 betweenRunnableand Threadclasses.
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 differentfrom
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
Callableand Runnable
.
15.What is the purpose of the
Futureinterface?
16.What is
ReentrantLockand how is it different from
synchronized?
17.How does the
CountDownLatchwork? When should you use it?
Concurrency Utilities
18.What is the difference between
CyclicBarrierand
CountDownLatch
?
9.Explain
1 Fork/Joinframework 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 samethread?
3.How can you stop a thread in Java? Why is
2 Thread.stop()deprecated?
24.How do you handle exceptions in multithreading?