CountDownLatch // 计数器
CyclicBarrier // 循环阻塞
Semaphore //信号量
CountDownLatch
java.util.concurrent
Class CountDownLatchjava.lang.Object
java.util.concurrent.CountDownLatch
public class CountDownLatch
extends Object解释: 允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
A
CountDownLatch
用给定的计数初始化。await
方法阻塞,直到由于countDown()
方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await
调用立即返回。 这是一个一次性的现象 - 计数无法重置。 如果您需要重置计数的版本,请考虑使用CyclicBarrier
。A
CountDownLatch
是一种通用的同步工具,可用于多种用途。 一个CountDownLatch
为一个计数的CountDownLatch用作一个简单的开/关锁存器,或者门:所有线程调用await
在门口等待,直到被调用countDown()
的线程打开。 一个CountDownLatch
初始化N可以用来做一个线程等待,直到N个线程完成某项操作,或某些动作已经完成N次
个人解释:
就是对线程计数,到达指定数量后,继续执行,否则等待
1 | /** |
结果:
CountDownLatch
线程1撤退!
线程2撤退!
线程5撤退!
线程6撤退!
线程9撤退!
线程0撤退!
线程3撤退!
线程4撤退!
线程7撤退!
线程8撤退!
结果:0 <-countDownLatch 为0 才执行
CyclicBarrier
java.util.concurrent
Class CyclicBarrierjava.lang.Object
java.util.concurrent.CyclicBarrier
public class CyclicBarrier
extends Object允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。
官方解释:
A
CyclicBarrier
支持一个可选的Runnable
命令,每个屏障点运行一次,在派对中的最后一个线程到达之后,但在任何线程释放之前。 在任何一方继续进行之前,此屏障操作对更新共享状态很有用。
个人解释:
当阻塞的线程到达一定的数量,线程才会继续执行cyclicBarrier定义好的
1 | public static void CyclicBarrierTest() { |
CyclicBarrier
线程0取得数据: 0
线程3取得数据: 3
线程4取得数据: 4
线程1取得数据: 1
线程2取得数据: 2
获取等待线程的数量 9
线程6取得数据: 6
线程5取得数据: 5
线程7取得数据: 7
线程8取得数据: 8
九之极, 万物演化 <- 9
Semaphore
java.util.concurrent
Class Semaphore
java.lang.Object
java.util.concurrent.SemaphoreAll Implemented Interfaces:
Serializable
public class Semaphore
extends Object
implements Serializable一个计数信号量。 在概念上,信号量维持一组许可证。 如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它。 每个release()添加许可证,潜在地释放阻塞获取方。 但是,没有使用实际的许可证对象; Semaphore只保留可用数量的计数,并相应地执行。
官方解释:
信号量通常用于限制线程数,而不是访问某些(物理或逻辑)资源。 例如,这是一个使用信号量来控制对一个项目池的访问的类
在获得项目之前,每个线程必须从信号量获取许可证,以确保某个项目可用。 当线程完成该项目后,它将返回到池中,并将许可证返回到信号量,允许另一个线程获取该项目。 请注意,当调用
acquire()
时,不会保持同步锁定,因为这将阻止某个项目返回到池中。 信号量封装了限制对池的访问所需的同步,与保持池本身一致性所需的任何同步分开。
个人解释:
相当于 限流
1 | public static void SemaphoreTest() { |
结果:
线程2取得数据: 2
线程0取得数据: 0
等待线程数: 7 <–
等待线程数: 7 <–
线程2:1秒后丢弃数据: 2
线程0:1秒后丢弃数据: 0
线程1取得数据: 1
线程3取得数据: 3
等待线程数: 5 <–
等待线程数: 5 <–
线程1:1秒后丢弃数据: 1
线程3:1秒后丢弃数据: 3
线程5取得数据: 5
线程6取得数据: 6
等待线程数: 3 <–
线程5:1秒后丢弃数据: 5
等待线程数: 3 <–
线程4取得数据: 4
线程6:1秒后丢弃数据: 6
线程7取得数据: 7
等待线程数: 1 <–
线程4:1秒后丢弃数据: 4
等待线程数: 1 <–
线程7:1秒后丢弃数据: 7
线程8取得数据: 8
等待线程数: 0 <–
线程8:1秒后丢弃数据: 8
小唠嗑:
本章到这里就结束了,谢谢耐心看到这里的各位Boss,如果觉得有哪里说的不好的地方,还请高抬贵手多多原谅,不惜指教。
最后,谢谢!