Multithreading & Concurrency - Java Focused Notes
1. What is Multithreading?
Multithreading is a programming technique where multiple threads run concurrently within a process. Each
thread runs a sequence of instructions independently. Java supports multithreading through the Thread class
and Runnable interface.
2. Creating Threads in Java
class MyThread extends Thread {
public void run() {
System.out.println("Hello from thread!");
}
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // starts a new thread
}
}
3. Race Condition Example
When two threads access a shared variable and try to change it at the same time, a race condition may
occur.
class Counter {
int count = 0;
public void increment() {
count++;
}
}
Above: Both threads read the same value before either writes back, resulting in one increment being lost.
© AlgoUniversity www.algouniversity.com
Multithreading & Concurrency - Java Focused Notes
4. Fixing Race Conditions Using Synchronized
class Counter {
int count = 0;
public synchronized void increment() {
count++;
}
}
5. Thread Pools
Creating too many threads can exhaust system resources. Thread pools reuse a fixed number of threads to
execute tasks.
Java provides ExecutorService for managing thread pools.
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(() -> System.out.println("Task executed"));
executor.shutdown();
}
}
6. Deadlock in Java
A deadlock occurs when two threads are waiting on each other to release resources.
class DeadlockExample {
static final Object lock1 = new Object();
static final Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
synchronized (lock2) {
System.out.println("Thread 1");
}
}
© AlgoUniversity www.algouniversity.com
Multithreading & Concurrency - Java Focused Notes
}).start();
new Thread(() -> {
synchronized (lock2) {
synchronized (lock1) {
System.out.println("Thread 2");
}
}
}).start();
}
}
7. Async vs Multithreading
- Multithreading: multiple threads run in parallel. Good for CPU-bound tasks.
- Asynchronous Programming: one thread manages multiple tasks using callbacks or futures. Good for
I/O-bound tasks.
© AlgoUniversity www.algouniversity.com
Comprehensive Java Multithreading & Concurrency Topics
I. Fundamentals
- Processes vs. Threads: Understand the difference between a process (an independent program) and a
thread (a unit of execution within a process).
- Thread Creation: Learn how to create threads using the Thread class and the Runnable interface.
- Thread Lifecycle: Study the different states of a thread: new, runnable, blocked, waiting, timed waiting, and
terminated.
- Thread Scheduling: Understand how the operating system manages thread execution and the concept of
thread priority.
- Concurrency vs. Parallelism: Differentiate between concurrency (multiple tasks seemingly executing at the
same time) and parallelism (actual simultaneous execution on multiple processors).
- Thread Safety: Learn how to write code that is safe to be executed by multiple threads concurrently,
avoiding race conditions.
II. Synchronization
- Synchronization: Understand the importance of synchronization for controlling access to shared resources.
- Synchronized Methods and Blocks: Learn how to use synchronized methods and blocks to protect critical
sections of code.
- Volatile Keyword: Understand how volatile ensures visibility of changes to a variable across threads.
- Locks and Thread Synchronization: Explore the use of ReentrantLock and other lock implementations for
more flexible synchronization.
- Inter-Thread Communication: Learn how to use wait(), notify(), and notifyAll() for communication between
threads.
- Producer-Consumer Problem: Study this classic concurrency pattern and its implementation using
synchronization and queues.
- ThreadLocal: Understand how ThreadLocal provides thread-specific storage for variables.
- Atomic Variables: Learn how to use atomic variables for thread-safe operations on individual variables.
III. Concurrency Utilities
- java.util.concurrent Package: Explore the rich set of classes and interfaces in this package for advanced
concurrency features.
- Executor Framework: Learn how to use the Executor framework for managing thread pools and executing
tasks.
- Callable and Future: Understand how to use Callable and Future for asynchronous computations.
Comprehensive Java Multithreading & Concurrency Topics
- CompletableFuture: Learn about CompletableFuture for asynchronous programming and combining results
from multiple threads.
- BlockingQueue: Study various implementations of BlockingQueue for thread-safe data exchange.
- CountDownLatch, CyclicBarrier, and Phaser: Understand how to use these synchronization aids for
coordinating the execution of multiple threads.
IV. Common Concurrency Issues
- Deadlock: Learn how to detect, prevent, and resolve deadlocks.
- Starvation and Fairness: Understand how some threads might be indefinitely delayed while others get
preferential treatment.