浏览量:143 最近编辑于:null
# CountDownLatch
作用:
用于让一个或多个线程等待其他线程完成操作后再继续执行。
通过一个计数器(count)来实现,计数器的初始值由构造方法指定。
每当一个线程完成任务后调用 countDown(),计数器减 1,当计数器减为 0 时,所有等待的线程会被唤醒。
常见场景:
主线程等待多个子线程完成任务。
模拟并发测试,确保多个线程同时开始执行
```java
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " is working...");
Thread.sleep(1000); // 模拟任务执行
System.out.println(Thread.currentThread().getName() + " finished.");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown(); // 计数器减 1
}
}).start();
}
System.out.println("Main thread is waiting...");
latch.await(); // 等待计数器减为 0
System.out.println("All threads have finished. Main thread continues.");
}
}
```
# CyclicBarrier
作用:
用于让一组线程互相等待,直到所有线程都到达某个屏障点(barrier)后再继续执行。
与 CountDownLatch 的区别是,CyclicBarrier 可以重复使用,而 CountDownLatch 只能使用一次。
常见场景:
多线程分阶段执行任务,所有线程在每个阶段都需要同步。
```java
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int threadCount = 3;
CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
System.out.println("All threads have reached the barrier. Proceeding to the next step...");
});
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " is working...");
Thread.sleep(1000); // 模拟任务执行
System.out.println(Thread.currentThread().getName() + " reached the barrier.");
barrier.await(); // 等待其他线程到达屏障
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
```
# Semaphore
作用:
用于控制同时访问某个资源的线程数量。
通过信号量(permits)限制资源的并发访问数量。
常见场景:
限制对某些资源(如数据库连接、文件等)的并发访问。
实现限流。
```java
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
int permits = 2; // 允许同时访问的线程数
Semaphore semaphore = new Semaphore(permits);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " is trying to acquire a permit...");
semaphore.acquire(); // 获取许可
System.out.println(Thread.currentThread().getName() + " acquired a permit.");
Thread.sleep(2000); // 模拟任务执行
System.out.println(Thread.currentThread().getName() + " is releasing a permit.");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放许可
}
}).start();
}
}
}
```
# 总结
工具 作用 常见场景
CountDownLatch 让一个或多个线程等待其他线程完成任务后再继续执行。 主线程等待多个子线程完成任务,模拟并发测试。
CyclicBarrier 让一组线程互相等待,直到所有线程都到达屏障点后再继续执行。 多线程分阶段执行任务,所有线程在每个阶段都需要同步。
Semaphore 控制同时访问某个资源的线程数量。 限制对资源的并发访问(如数据库连接池、限流)。
区别:
CountDownLatch:
一次性使用,计数器减到 0 后不能重置。
适用于主线程等待子线程完成任务的场景。
CyclicBarrier:
可重复使用,适用于多线程分阶段同步的场景。
提供一个可选的 Runnable,在所有线程到达屏障点时执行。
Semaphore:
用于控制并发访问的线程数量。
适用于限流或资源池管理的场景。