1.CountDownLatch基础概念和使用
2.CyclicBarrier基础概念和使用
3.Semaphore基础概念和使用
1.CountDownLatch基础概念和使用
通俗的来说,CountDownLatch的功能就是让一些线程等待直到另外的一些线程全部运行结束之后,再开始运行。
举个例子:
一个教室每天都要安排一个同学值日关门,这个同学一定要等到其他同学全部离开之后(等待其它线程全部执行完毕),才能把门关上(才会往下执行)。
我们用代码来证明一下上述的例子:
首先,我们要用到三个重要的方法:
//构造方法的数字表示,要等五个线程运行完毕后,才会继续往下执行
CountDownLatch countDownLatch = new CountDownLatch(5);
//需要等待的线程减一(相当于一个同学离开了教师)
countDownLatch.countDown();
//等待其它所有线程执行完毕,再往下执行(再往下执行关门动作)
countDownLatch.await();
CountDownLatch countDownLatch = new CountDownLatch(5);
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
System.out.println("第" + Thread.currentThread().getName() + "个同学离开教室");
//一个同学离开后,需要等待的线程就减一
countDownLatch.countDown();
}, i + "").start();
}
//到这儿等待
countDownLatch.await();
new Thread(() -> {
System.out.println("班长离开教室");
}).start();
执行结果为:
可以看出,countDownLatch等待其它线程执行完毕做的是减法操作。
2.CyclicBarrier基础概念和使用
如果说countDownLatch是做减法,CyclicBarrier就是做加法。
举个例子:集齐七颗龙珠召唤神龙!(等待七个线程运行完毕,然后执行最终的线程。)
同样地我们要用到两个方法:
//构造函数可以传指定线程的数量,以及线程数量到达后的完成方法,可用lambda表达式完成。
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙!");
});
//当一个线程执行完毕后,调用这个方法表示已经执行的线程+1(已收集的龙珠+1)
cyclicBarrier.await();
我们将举例用代码实现一次:
//设置等待的线程总数和完成之后的方法内容
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙!");
});
for (int i = 1; i <= 7; i++) {
final int num = i;
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "收集到第" + num + "颗龙珠");
try {
//完成线程数+1
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, i + "").start();
}
运行结果为:
可以得出,CyclicBarrier是一个做加法的操作,线程增加到一定程度,就可以执行最终的线程。(就好像人到齐了再开会。)
3.Semaphore基础概念和使用
Semaphore是一种信号量,我们可以用“抢车位”来形容这个类,就像多辆车竞争多个车位。(多个线程争抢多个资源。)
我们仍然用代码来完成上面的举例:
//一共有三个资源
Semaphore semaphonre = new Semaphore(3);
//获得资源
semaphonre.acquire();
//释放资源
semaphonre.release();
Semaphore semaphonre = new Semaphore(3);
for (int i = 1; i <= 5; i++) {
final int temp = i;
new Thread(() -> {
try {
semaphonre.acquire();
System.out.println("第" + temp + "辆车进入停车位");
Thread.sleep(3000);
System.out.println("第" + temp + "辆车,停车3秒后离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphonre.release();
}
}, i + "").start();
}
运行结果为:
可以看出,每次最多只能有三个停车位进入,否则就阻塞。
总结:
CountDownLatch:做减法,当计数器变为0的时候,调用await的线程会被唤醒,继续执行。
CyclicBarrier:做加法,等到一定数量的线程执行,再继续执行最终的方法。
Semaphore:多个线程争抢多个资源。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。