1.Tools介绍
Tools也是JUC中的工具类,其中包含了CountDownLatch、CyclicBarrier、Semaphore
2.CountDownLatch计数器
在开发中经常遇到在主线程中开启多个线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后再进行汇总的场景。之前是使用join() | 主线程休眠实现的,但是不够灵活,某些场合和还无法实现,所以开发了CountDownLatch这个类。底层基于AQS。
CountDown是计数递减的意思,Latch是门闩的意思。内部维持一个递减的计数器。可以理解为初始有n个Latch,等Latch数量递减到0的时候,结束阻塞,执行后续操作。
创建:
CountDownLatch cdl= new CountDownLatch(数字);
线程等待:
当前线程等待,直到到Latch计数到零,或者被interrupt
cdl.await():
计数器递减:
减少Latch的计数,如果计数达到零,释放等待的线程
cdl.countDown( ):
3.CyclicBarrier回环屏障
CountDownLatch优化了join()在解决多个线程同步时的能力,但CountDownLatch的计数器是一次性的。计数递减为0之后,再调用countDown()、await()将不起作用。为了满足计数器可以重置的目的,JDK推出了CyclicBarrier类。
await()方法表示当前线程执行时计数器值不为0则等待。如果计数器为0则继续执行。每次await()之后计算器会减少一次。当减少到0下次await从初始值重新递减。
4.Semaphore信号量
CountDownLatch和CyclicBarrier的计数器递减的,而Semaphore的计数器是可加可减的,并可指定计数器的初始值,并且不需要事先确定同步线程的个数,等到需要同步的地方指定个数即可。且Semaphore也具有回环重置的功能,这一点和CyclicBarrier很像。底层也是基于AQS。
创建:
Semaphore sp= new Semaphore(数字);
获取信号量的值:
int i = sp.availablePermits();
增加信号量:
//信号量+1
sp.release();
//信号量+n
sp.release(n);
减少信号量:
sp.acquire(); //信号量-1,无返回值
sp.tryAcquire(); //信号量-1,有返回值
sp.acquire(n); //信号量-n,无返回值
sp.tryAcquire(n); //信号量-n,有返回值