CountDownLatch
- 描述:CountDownLatch是一个同步辅助类,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。它通过一个计数器来实现,该计数器初始化为一个正整数,表示需要等待的操作数。每当一个操作完成时,计数器减1,当计数器减到0时,所有等待的线程将被释放。
- 适用场景:适用于需要等待一组操作全部完成后,再继续执行后续操作的场景。例如,在多线程计算任务中,等待所有子任务计算完成后,汇总结果。
- 代码示例:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) {
int taskCount = 3;
CountDownLatch latch = new CountDownLatch(taskCount);
for (int i = 0; i < taskCount; i++) {
new Thread(new Worker(latch)).start();
}
try {
latch.await();
System.out.println("所有任务已完成,主线程继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class Worker implements Runnable {
private final CountDownLatch latch;
Worker(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始执行任务");
// 模拟任务执行
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " 任务完成");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
}
}
CyclicBarrier
- 描述:CyclicBarrier也是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(barrier point)。与CountDownLatch不同的是,CyclicBarrier的计数器可以重置,即可以重复使用。当所有线程到达屏障点时,屏障打开,所有线程可以继续执行,之后计数器重置,可以再次使用。
- 适用场景:适用于需要多线程之间相互等待,并且这种等待可以循环进行的场景。例如,在多线程迭代计算中,每一轮计算都需要等待所有线程完成当前轮次后,再开始下一轮。
- 代码示例:
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int parties = 3;
CyclicBarrier barrier = new CyclicBarrier(parties, () -> {
System.out.println("所有线程已到达屏障点,开始下一轮");
});
for (int i = 0; i < parties; i++) {
new Thread(new Worker(barrier)).start();
}
}
static class Worker implements Runnable {
private final CyclicBarrier barrier;
Worker(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始执行任务");
// 模拟任务执行
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " 等待其他线程到达屏障点");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Semaphore
- 描述:Semaphore是一个计数信号量,它维护了一组许可证(permit)。线程可以通过acquire()方法获取许可证,如果没有可用许可证,线程将被阻塞,直到有许可证可用。线程使用完许可证后,通过release()方法释放许可证。
- 适用场景:适用于控制对共享资源的并发访问数量。例如,数据库连接池,限制同时连接数据库的线程数量。
- 代码示例:
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(new Worker(semaphore)).start();
}
}
static class Worker implements Runnable {
private final Semaphore semaphore;
Worker(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " 获取到许可证,开始执行任务");
// 模拟任务执行
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " 任务完成,释放许可证");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
}