简要说明
- CountDownLatch: 主要用来保证所有线程都结束后才能往下走
- CyclicBarrier:主要用来保证运行中的所有线程到达预定点后,每个线程再往下走
- Semaphore:用来控制线程创建个数,和线程池的道理差不多,更简单粗暴
- Exchanger:用来线程间交换信息,传递信息。会一直拿到另一端的信息才会往下走
CountDownLatch
示意图

代码示例
public static void main(String[] args) throws InterruptedException {
Calendar startTime = Calendar.getInstance();
// 参数代表有几个线程, 3代表3个
CountDownLatch countDownLatch = new CountDownLatch(3);
new TestThread(countDownLatch).start();
new TestThread(countDownLatch).start();
new TestThread(countDownLatch).start();
// 等待线程结束
countDownLatch.await();
Calendar endTime = Calendar.getInstance();
System.out.println(String.format("主程序等待了%d秒", (endTime.getTimeInMillis() - startTime.getTimeInMillis())/1000));
}
static class TestThread extends Thread {
CountDownLatch countDownLatch;
TestThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
Random random = new Random();
int waitSecond = random.nextInt(10);
Thread.sleep(waitSecond * 1000);
System.out.println(String.format("执行了%d秒", waitSecond));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 关键句,相当于说我执行完了
countDownLatch.countDown();
}
}
}

可以看到, 会以最长执行时间的线程执行时间
CyclicBarrier
示意图

public static void main(String[] args) throws InterruptedException {
Calendar startTime = Calendar.getInstance();
// 参数代表有几个线程, 3代表3个
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
new TestThread(cyclicBarrier).start();
new TestThread(cyclicBarrier).start();
new TestThread(cyclicBarrier).start();
Calendar endTime = Calendar.getInstance();
System.out.println(String.format("主程序等待了%d秒", (endTime.getTimeInMillis() - startTime.getTimeInMillis())/1000));
}
static class TestThread extends Thread {
CyclicBarrier cyclicBarrier;
TestThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
Random random = new Random();
int waitSecond = random.nextInt(10);
Thread.sleep(waitSecond * 1000);
System.out.println(String.format("%s到达时间%s", this.getName(), Calendar.getInstance().getTime()));
// 关键语句,会等待所有标记的线程到这个点
cyclicBarrier.await();
System.out.println(String.format("%s放行时间%s", this.getName(), Calendar.getInstance().getTime()));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}

可以看到,这里主线程没有等待,而是线程会停到一个点,等最后一个线程执行到这个点才会往下执行
本文介绍了Java中四种重要的并发控制工具:CountDownLatch用于等待所有线程完成;CyclicBarrier让线程在预定点同步;Semaphore限制线程数量;Exchanger用于线程间信息交换。通过示例代码展示了它们各自的工作原理和使用场景。
265

被折叠的 条评论
为什么被折叠?



