CountDownLatch/CyclicBarrier/Semaphore
升级前后对比!!
1.CountDownLatch
目的:让一些线程阻塞直到另一个线程完成一系列操作后才被唤醒!
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。
其他线程调用countDown方法会将计数器减1(调用CountDown方法的线程不会阻塞),当计数器的值变为0时,因调用await方法被阻塞的线程会被唤醒,继续执行。
秦灭六国,统一天下!
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for(int i = 1;i <=6;i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "\t 国灭亡");
countDownLatch.countDown();
},CountryEnum.forEach_CountryEnum(i).getRetMessage()).start();
}
//阻塞main线程,当计数器为0时,唤醒main
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "====秦统一");
}
2.CyclicBarrier
CyslicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。
它要做的事情是,让一组线程到达屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会打开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。
先收集龙珠,最后召唤神龙
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()-> System.out.println("召唤神龙*********"));
for(int i = 1;i <=7;i++){
final int tempInt = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t收集到第:"+tempInt+"龙珠");
try {cyclicBarrier.await();} catch (Exception e) {e.printStackTrace();}
},String.valueOf(i)).start();
}
}
3.Semaphore
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。
6个车争3个车位
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);//模拟3个停车位
for(int i = 1;i <=6;i++){//模拟6部汽车
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"\t抢到车位");
//暂停一会线程
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t停车3秒后离开");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
----out
1 抢到车位
2 抢到车位
3 抢到车位
2 停车3秒后离开
3 停车3秒后离开
1 停车3秒后离开
5 抢到车位
4 抢到车位
6 抢到车位
5 停车3秒后离开
4 停车3秒后离开
6 停车3秒后离开