如何让 Java 的线程彼此同步?你了解过哪些同步器? 请分别介绍下。

JUC 中的同步器三个主要的成员:CountDownLatch、CyclicBarrier 和 Semaphore,通过它们可以方便地实现很

多线程之间协作的功能。 CountDownLatch 叫倒计数,允许一个或多个线程等待某些操作完成。看几个场景:

  • 跑步比赛,裁判需要等到所有的运动员(“其他线程”)都跑到终点(达到目标),才能去算排名和颁奖。
  • 模拟并发,我需要启动100个线程去同时访问某一个地址,我希望它们能同时并发,而不是一个一个的去执行。

用法:CountDownLatch 构造方法指明计数数量,被等待线程调用 countDown 将计数器减1,等待线程使用 await 进行线程等待。一个简单的例子:

2022012402280227
CyclicBarrier 叫循环栅栏,它实现让一组线程等待至某个状态之后再全部同时执行,而且当所有等待线程被释放后,CyclicBarrier 可以被重复使用。CyclicBarrier 的典型应用场景是用来等待并发线程结束。 CyclicBarrier 的主要方法是 await(),await()每被调用一次,计数便会减少1,并阻塞住当前线程。当计数减至0时,阻塞解除,所有在此 CyclicBarrier 上面阻塞的线程开始运行。
在这之后,如果再次调用 await(),计数就又会变成 N-1,新一轮重新开始,这便是 Cyclic 的含义所在。CyclicBarrier.await()带有返回值,用来表示当前线程是第几个到达这个 Barrier 的线程。

举例说明如下:

2022012402281653

Semaphore,Java 版本的信号量实现,用于控制同时访问的线程个数,来达到限制通用资源访问的目的,其原理是通过 acquire()获取一个许可,如果没有就等待,而 release()释放一个许可。

2022012402282836
如果 Semaphore 的数值被初始化为1,那么一个线程就可以通过 acquire 进入互斥状态,本质上和互斥锁是非常相似的。但是区别也非常明显,比如互斥锁是有持有者的,而对于 Semaphore 这种计数器结构,虽然有类似功能,但其实不存在真正意义的持有者,除非我们进行扩展包装。

回复

我来回复
  • 暂无回复内容

免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部