1.CountDownLatch案例
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。
当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行
//未使用CountDownLatch
public class CountDownLatchDemo {
public static void main(String[] args) {
for (int i = 1; i <=6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 上玩自习,走人");
},i+"").start();
}
System.out.println(Thread.currentThread().getName()+"\t ****班长最后关门走人");
}
}
//输出信息 --- 导致人没有走人,门就被锁上
1 上玩自习,走人
4 上玩自习,走人
3 上玩自习,走人
2 上玩自习,走人
main ****班长最后关门走人
5 上玩自习,走人
6 上玩自习,走人
---------------------------------------------------------------------------------------
//使用CountDownLatch
public class CountDownLatchDemo {
public static void main(String[] args) throws Exception{
CountDownLatch cdl=new CountDownLatch(6);
for (int i = 1; i <=6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 上玩自习,走人");
cdl.countDown();
},i+"").start();
}
cdl.await();
System.out.println(Thread.currentThread().getName()+"\t ****班长最后关门走人");
}
}
//输出信息
1 上玩自习,走人
4 上玩自习,走人
3 上玩自习,走人
2 上玩自习,走人
5 上玩自习,走人
6 上玩自习,走人
main ****班长最后关门走人
2.CyclicBarrier案例
与CountDownLatch相反,CyclicBarrier是累加到一个值才会被执行
SyclicBarrier的字面意思是可循环(Syclic)使用屏障(Barrier)。他主要的事情是让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程达到屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await方法。
public class CyclicBarrierDemo {
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();
}
},i+"").start();
}
}
}
//输出信息
1 收集到第:1颗龙珠
3 收集到第:3颗龙珠
2 收集到第:2颗龙珠
5 收集到第:5颗龙珠
4 收集到第:4颗龙珠
6 收集到第:6颗龙珠
7 收集到第:7颗龙珠
******召唤神龙*****
3.Semaphore案例
信号量主要用于两个目的,一个是用于多个共享资源的互斥作用,另一个用于并发线程数的控制
//模拟抢车位
public class SemaphoreDemo {
public static void main(String[] args) {
//模拟3个停车位
Semaphore semaphore = new Semaphore(3);
//模拟6部汽车
for (int i = 1; i 6; i++) {
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();
}
}
}