Detailed Explanation of J.U.C Concurrency Utility Classes in Java
I. Overview of J.U.C
J.U.C (java.util.concurrent) is a concurrency programming toolkit provided by Java, containing three major categories of components to solve concurrency problems:
- Atomic Classes - Thread-safe atomic operation classes
- Lock Mechanisms - More flexible locks than synchronized
- Concurrent Collections - Thread-safe collection containers
- Thread Pools (Executor) - Thread management and scheduling
- Synchronization Utilities - Tool classes for controlling thread execution
II. CountDownLatch
-
Core Function: Allows one or more threads to wait for other threads to complete operations
-
Implementation Principle:
- Internally maintains a counter, initialized with the number of threads to wait for
- Each thread calls countDown() upon completion, decrementing the counter by 1
- When the counter reaches 0, waiting threads are awakened
-
Code Example:
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3); // Initial counter set to 3
for (int i = 1; i <= 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " Task completed");
latch.countDown(); // Counter decrement
}, "Thread" + i).start();
}
latch.await(); // Main thread waits until counter reaches 0
System.out.println("All threads completed tasks, main thread continues execution");
}
}
III. CyclicBarrier
-
Core Function: Allows a group of threads to wait for each other, proceeding only after reaching a common barrier point
-
Differences from CountDownLatch:
- CountDownLatch is single-use, CyclicBarrier is reusable
- CountDownLatch involves main thread waiting, CyclicBarrier involves mutual waiting among threads
-
Code Example:
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads reached barrier, executing barrier action");
});
for (int i = 1; i <= 3; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " Reached barrier");
barrier.await(); // Wait for other threads
System.out.println(Thread.currentThread().getName() + " Continuing execution");
} catch (Exception e) {
e.printStackTrace();
}
}, "Thread" + i).start();
}
}
}
IV. Semaphore
-
Core Function: Controls the number of threads that can simultaneously access a specific resource
-
Two Modes:
- Fair mode: Permits acquired in order of request
- Non-fair mode: Permits acquired preemptively
-
Code Example:
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); // Allows 3 concurrent thread accesses
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try {
semaphore.acquire(); // Acquire permit
System.out.println(Thread.currentThread().getName() + " Acquired resource");
Thread.sleep(2000); // Simulate resource usage
System.out.println(Thread.currentThread().getName() + " Released resource");
semaphore.release(); // Release permit
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thread" + i).start();
}
}
}
V. Exchanger
-
Core Function: Used for data exchange between two threads
-
Execution Flow:
- Thread A blocks after executing exchange(), waiting for Thread B
- Thread B executes exchange(), both threads exchange data and continue execution
-
Code Example:
public class ExchangerDemo {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
try {
String dataA = "Data A";
System.out.println("Thread A sending: " + dataA);
String result = exchanger.exchange(dataA);
System.out.println("Thread A received: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
String dataB = "Data B";
System.out.println("Thread B sending: " + dataB);
String result = exchanger.exchange(dataB);
System.out.println("Thread B received: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
VI. Phaser
-
Core Function: More flexible reusable synchronization barrier supporting dynamic adjustment of participating threads
-
Core Concepts:
- Phase: Numbered starting from 0, increments after all threads complete
- Registration: Dynamically increases or decreases participating thread count
-
Code Example:
public class PhaserDemo {
public static void main(String[] args) {
Phaser phaser = new Phaser(3) { // Initial 3 participating threads
@Override
protected boolean onAdvance(int phase, int registeredParties) {
System.out.println("Phase " + phase + " completed");
return registeredParties == 0; // Returns true to terminate Phaser
}
};
for (int i = 1; i <= 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " Completed phase 0");
phaser.arriveAndAwaitAdvance(); // Wait for other threads
System.out.println(Thread.currentThread().getName() + " Completed phase 1");
phaser.arriveAndAwaitAdvance();
phaser.arriveAndDeregister(); // Complete task and deregister
}, "Thread" + i).start();
}
}
}
VII. Tool Class Comparison Summary
| Tool Class | Core Function | Reusability | Characteristics |
|---|---|---|---|
| CountDownLatch | Wait for specified number of tasks to complete | No | Single-use, main thread waits |
| CyclicBarrier | Mutual waiting among threads | Yes | Reusable, supports barrier action |
| Semaphore | Control resource access quantity | Yes | Supports fair/non-fair modes |
| Exchanger | Data exchange between threads | Yes | Supports exchange between only two threads |
| Phaser | Multi-phase task synchronization | Yes | Most flexible, supports dynamic adjustment |
VIII. Usage Scenario Analysis
- CountDownLatch: Main thread waits for all subtasks to complete
- CyclicBarrier: Multi-threaded computation, merging calculation results
- Semaphore: Database connection pool rate limiting
- Exchanger: Data verification between two threads
- Phaser: Complex multi-phase task coordination
These utility classes provide higher-level thread coordination mechanisms than wait/notify, simplifying development of complex concurrency scenarios.