CyclicBarrier 与 CountDownLatch

本贴最后更新于 1825 天前,其中的信息可能已经时过境迁

alexlisovenko7UyAY4ao7sYunsplash.jpg

功能

  • CyclicBarrier
    • 调用 await 方法休眠线程,当所有线程都执行到达 await 点时,唤醒所有线程然后才执行后续代码
    • 唤醒所有线程后,CyclicBarrier 进入下一个周期 意味着可以重复使用
  • CountDownLatch
    • 调用 await 休眠线程,当调用指定次数 countDown 后唤醒所有 await 的线程
    • 执行了唤醒所有线程后,await 方法就会失效 意味着不可以重复使用

CyclicBarrier 可以重复使用的原因

  • 关键代码 ->await->dowait->nextGeneration
private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { final ReentrantLock lock = this.lock; lock.lock(); try { final Generation g = generation; if (g.broken) throw new BrokenBarrierException(); if (Thread.interrupted()) { breakBarrier(); throw new InterruptedException(); } int index = --count; if (index == 0) { // tripped boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run(); ranAction = true; nextGeneration(); return 0; } finally { if (!ranAction) breakBarrier(); } } ...... } ------------------------------------------------ private void nextGeneration() { // signal completion of last generation trip.signalAll(); // set up next generation count = parties; generation = new Generation(); }
  • 最终会执行 nextGeneration 方法
    • 该方法会唤醒所有的休眠线程
    • 然后又把 count 重置为初始值 count值用来计数休眠的线程,当count为0时表示该唤醒所有线程了

CountDownLatch

Syn

CountDownLatch 使用的 AQS,主要定义了一个内部类 Sync 实现 AQS

因为 CountDownLatch 是共享锁,所以 Sync 重载的 tryAcquireSharedtryReleaseShared

当初始化 CountDownLatch 时需要指定数量,最后这个数量会被 Syn 使用,作为 AQS 的 state

流程

  • 当调用 await 方法时,会生成节点插入到 AQS 的同步队列中然后使用 LockSupport 挂起线程
  • 使用 countDown 方法时会调用 Syn 的 tryReleaseShared 方法将 state 的值减一,当 state 被减为 0 时,AQS 会调用 doReleaseShared 唤醒所有的线程
  • 代码
    470 引用 • 591 回帖 • 9 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3203 引用 • 8217 回帖 • 2 关注
1 操作
614756773 在 2020-07-26 15:45:49 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...