一.Semaphore
Semaphore semaphore =new Semaphore(2);-----他是一个AQS的共享锁,可以允许多个线程拿到资源
1.semaphore.acquire() --------表示阻塞并获取许可
public void acquire()throws InterruptedException {
sync.acquireSharedInterruptibly(1); //调用此方法,通过传参可以看出,调用一次acquire(),获取一个公共资源
}
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted()) //判断此线程是否已经中断
throw new InterruptedException();
if (tryAcquireShared(arg) <0) //tryAcquireShared(arg)方法本质调用Sync中的tryAcquireShared()方法,方法内部操作看下图解析
doAcquireSharedInterruptibly(arg);
}
2.semaphore.release() ----------表示释放许可(释放公共资源)
主要作用:他是一个计数信号,主要需求场景是进行 资源访问,服务限流
semaphore默认创建非公平锁
二.CountDownLatch
1.概念:
CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行,例如我们打游戏,加载游戏,必须所有玩家都加载成功,才能进入游戏
2.如何工作
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量,每当一个线程完成了自己的任务,计数器就会减1,当计数器值到达0时,它表示所有的线程已经完成任务,然后在闭锁上等待线程就可以恢复执行任务
3.API
CountDownLatch.countDown() //计数器减1
CountDownLatch.await();//等待所有线程执行完毕
三.CyclicBarrier
1.概念:
栅栏屏障,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程
到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线
程数量,每个线程调用await方法告CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
2.API
cyclicBarrier.await()
CyclicBarrier必须等到所有初始化的线程都到达同步点,才能继续执行下一步,只要有一个没有到达,那么其他的线程就会一直等待
CyclicBarrier和CountDownLatch还有一个区别就是CyclicBarrier是可以重复使用的