本文将介绍一下CountDownLatch 、 CyclicBarrier 、 Semaphore这几个控制线程的类。
一、CountDownLatch
1、是什么?
这是一个计数器,而且是倒计时。就像火箭发射,10,9,8,……,0,到了0火箭才会发射。这个也一样,当里面的线程执行完,外面的线程才会执行。用一句话讲就是:秦灭六国,一统华夏。灭六国是是六个线程,等这六个线程执行完,一统华夏这个线程才能进行。
欢迎大家关注我的公众号 javawebkf,目前正在慢慢地将简书文章搬到公众号,以后简书和公众号文章将同步更新,且简书上的付费文章在公众号上将免费。
2、怎么用?
- 创建CountDownLatch对象,
CountDownLatch count = new CountDownLatch(6);
参数表示需要执行的线程的数量; - 每执行完一个线程,
count.countDown()
; - 需要等待的线程
count.await()
。
3、用之前怎么样?
话不多说,直接撸代码:
public static void main(String[] args) throws Exception{
for (int i = 1; i <= 6; i++) {
final int temp = i;
new Thread(() -> {
System.out.println("第 " + temp + "个国家被灭!");
}, "i").start();
}
System.out.println("六国被灭,秦一统华夏!");
}
我们的本意是:循环里面的六个线程执行完,主线程才能输出“六国被灭,秦一统华夏!”这句换,看看执行结果是否如尝所愿:
才灭了三个国家,那统一个锤子。
4、用之后怎么样?
public static void main(String[] args) throws Exception{
CountDownLatch count = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
final int temp = i;
new Thread(() -> {
System.out.println("第 " + temp + "个国家被灭!");
count.countDown();
}, "i").start();
}
count.await();
System.out.println("六国被灭,秦一统华夏!");
}
这就符合了预期。
二、CyclicBarrier
1、是什么?
上面说的CountDownLatch 是倒计数,那么这个就是顺数的。一句话:集齐七颗龙珠,才能召唤神龙。只有集龙珠这七个线程执行完,召唤神龙的线程才能执行。
2、怎么用?
- 创建对象,两个参数(1、集多少颗龙珠,2、new 一个线程,执行集齐龙珠后要做的事),
CyclicBarrier barrier = new CyclicBarrier(7,() -> {System.out.println("集齐七颗龙珠,召唤神龙!");});
- 每执行完一个线程,
barrier.await()
。
3、用之前怎么样?
public static void main(String[] args) throws Exception{
for (int i = 1; i <= 7; i++) {
final int temp = i;
new Thread(() -> {
System.out.println("收集到第 " + temp + "颗龙珠!");
}, "i").start();
}
System.out.println("集齐七颗龙珠,召唤神龙!");
}
可以看到,才收集到一颗龙珠,就召唤神龙,那能召唤出来?别做梦了。
4、用之后怎么样?
public static void main(String[] args) throws Exception{
CyclicBarrier barrier =
new CyclicBarrier(7,() -> {System.out.println("集齐七颗龙珠,召唤神龙!");});
for (int i = 1; i <= 7; i++) {
final int temp = i;
new Thread(() -> {
System.out.println("收集到第 " + temp + "颗龙珠!");
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}, "i").start();
}
}
这才是召唤神龙的正确操作!
三、Semaphore
1、是什么?
顺数计数和倒数技术都有了,那这个Semaphore是什么鬼?翻译过来意思是信号灯。一句话:抢车位。有三个车位,现在有六辆车。那么先是六辆车去抢三个车位,没抢到的就等着。等车位里面的车走了一辆,那么等待车就可以进去一辆。
2、怎么用?
- 创建对象,一个参数(车位的数量),
- 抢车位,
semaphore.acquire();
- 离开车位,
semaphore.release();
代码说话:
public static void main(String[] args) throws Exception{
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
final int temp = i;
new Thread(() -> {
try {
semaphore.acquire();
System.out.println("第 " + temp + "辆车抢到车位!");
TimeUnit.SECONDS.sleep(3);
System.out.println("3秒后第" + temp + "辆车离开车位!");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "i").start();
}
}
符合预期,一开始进去三辆,然后等有车离开了其他的才能进去。
总结:
以上就是三个线程控制类的用法,一个倒数计数、一个顺数计数、另一个就是抢车位的情况。