CountDownLatch的字面意思:倒计时
它的功能是:让一些线程阻塞直到另一些线程完成一系列操作后才唤醒。
它通过调用await方法让线程进入阻塞状态等待倒计时0时唤醒。
它通过线程调用countDown方法让倒计时中的计数器减去1,当计数器为0时,会唤醒哪些因为调用了await而阻塞的线程。
假设老板开一个紧急会议,他先到会议室等着所有人签到然后开始开会,可以使用CountDownLatch进行模拟。
public static void main(String[] args) {
CountDownLatch countDownLatch=new CountDownLatch(5);
for (int i=1;i<=5;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"签到!");
countDownLatch.countDown();
},"第"+i+"個人").start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("老板宣布人夠了开始开会!");
}
运行结果:
//注意这里的签到顺序可以随意
第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!
CyclicBarrier [?sa?kl?k] [?b?ri?r] 的字面意思:可循环使用的屏障
它的功能是:让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障,所有被屏障拦截的线程才会继续执行。
它通过调用await方法让线程进入屏障,
还是上面的开会的例子,我们使用CyclicBarrier实现。
public static void main(String[] args) {
CyclicBarrier cyclicBarrier=new CyclicBarrier(5,()->{
System.out.println("老板宣布人夠了开始开会!!");
});
for (int i=1;i<=5;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"签到!");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"第"+i+"個人").start();
}
}
运行结果:
第1個人签到!
第2個人签到!
第3個人签到!
第4個人签到!
第5個人签到!
老板宣布人夠了开始开会!!
Semaphor [?sem?f??r] 信号量的意思;
它主要用于两个目的:
//permits :允许
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//还可以指定是否为公平锁
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
假设现在是年终,总经理和副总经理要求所有部分要进行述职汇报工作,这两个老总为了提高效率在办公室里决定并行听取工作,使用Semaphor进行模拟。
根据需求我们可以确定共享资源为两个老总,并发汇报工作的最多两个部门。
public static void main(String[] args) {
Semaphore semaphore=new Semaphore(2);
for (int i=1;i<=6;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"到了办公室门口,等待述职!");
semaphore.acquire();
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
System.out.println(Thread.currentThread().getName()+"述职中完毕!");
}
},"第"+i+"部门").start();
}
}
运行效果:
第1部门到了办公室门口,等待述职!
第2部门到了办公室门口,等待述职!
第3部门到了办公室门口,等待述职!
第4部门到了办公室门口,等待述职!
第6部门到了办公室门口,等待述职!
第5部门到了办公室门口,等待述职!
第1部门述职中完毕!
第2部门述职中完毕!
第3部门述职中完毕!
第4部门述职中完毕!
第6部门述职中完毕!
第5部门述职中完毕!
注意结果:第1部门和第2部门是同时进行述职的,是两两进行的,也就是说我们控制了多线程情况下对共享资源访问时并发线程的数量。
CountDownLatch是做减法,CyclicBarrier是做加法,Semaphor的临界资源可以反复使用
CountDownLatch不能重置计数,CycliBarrier提供的reset()方法可以重置计数,不过只能等到第一个计数结束。Semaphor可以重复使用。
CountDownLatch和CycliBarrier不能控制并发线程的数量,Semaphor可以实现控制并发线程的数量。
CountDownLatch和CylicBarrier以及Semaphare你使用过吗
原文:https://www.cnblogs.com/wangsen/p/11170709.html