1.CountDownLatch
- CountDown减法计数,Latch门闩的意思
- 让一些线程阻塞直到另外一些完成后才被唤醒。
- 举例:
1,值日生要等所有人走后,才能打扫卫生关灯锁门
- Demo:
/**
* 值日生要等所有人走后,才能打扫卫生关灯锁门
*
* @author wangjie
* @version V1.0
* @date 2019/12/19
*/
public class CountDownLatchDemo1 {
public static void main(String[] args) throws Exception {
closeDoor();
}
/**
* 值日生案例
* @throws InterruptedException
*/
private static void closeDoor() 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();
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "\t值日生打扫卫生锁门");
}
}
-运行结果:
2.CyclicBarrier
- 可循环的屏障,让一组线程到达一个屏障时被阻塞,直到最后一个线程到达该屏障,屏障才会开门,所有被屏障拦截的线程才回继续工作。
- 举例:
集齐七龙珠才能召唤神龙。
- Demo:
/**
* 集齐七龙珠才能召唤神龙。
*
* @author wangjie
* @version V1.0
* @date 2019/12/19
*/
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 temp = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 收集到第"+ temp +"颗龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
- 运行结果:
2.1 CountDownLatch与CyclicBarrier区别
进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。
对于CountDownLatch,其他线程为其他同学,值日生是主线程,在其他同学离开前,值日生是不能关门的。
对于CyclicBarrier,每一个颗龙珠都是一个“其他线程”。当龙珠都集齐后之后,才召唤神龙。而主线程可能早就结束了,这里我们不用管主线程。
3.Semaphore
-
信号量两个目的,一个用于多个共享资源的相互排斥,另一个对并发资源数的控制。
-
举例:
抢车位
- Demo:
/**
* 抢车位
*
* @author wangjie
* @version V1.0
* @date 2019/12/19
*/
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();
}
}
}
- 运行结果:
【完】
注:文章内所有测试用例源码:https://gitee.com/wjie2018/test-case.git