一入王者深似海,从此对象是路人。
哈喽观众老爷们大家好,我是战神吕布字奉先,今天给大家来一部吕布的教学视频!
咳咳,不对。大家好,我是磊哥,今天给大家来一篇 CountDownLatch 的文章。
在开始之前,先问大家一个非常专业的技术性问题:打团战最怕_____?
一道非常简单的送分题,如果答不对,那磊哥就要批评你了,哈哈。
可能有人会说:打团战最怕猪队友,但比猪队友更可怕的是打团战人不齐啊兄弟,想想在打团时如果是 5V2 是怎么一幅画面,心痛到不敢想🤦🏻♀️。
等人齐再团
磊哥在儿子没有出生之前,也是资深的农药玩家,至于段位吗?别问!问就是青铜。虽然磊哥的段位不是很高,但基本的大局观还是有的,毕竟也是打过几年 Dota 和 LOL 的青铜玩家是吧?哈哈。
农药和其他 Moba 类游戏是一样的,想要取胜,必须要把握好每次团战,而每次团战的关键在于等人齐了再开团,是吧?而这个思想正好和咱们要讲得 CountDownLatch 的思想是一致的,咱们来看看是怎么回事吧。
吾有上将“CountDownLatch”
想象一下这样一个场景,当我们需要等待某些线程执行完之后,再执行主线程的代码,要怎么实现?
可能有人会说,简单,用 join() 方法等待线程执行完成之后再执行主线程就行了,实现代码是这样的:
// 创建线程1 Thread t1 = new Thread(new Runnable() { @Override public void run() { // do something } }); t1.start(); // 创建线程2 Thread t2 = new Thread(new Runnable() { @Override public void run() { // do something } }); t2.start(); // 等待线程 1和线程 2 执行完 t1.join(); t2.join();
当然,如果使用的是 Thread 来执行任务,那这种写法也是可行的。然而真实的(编码)环境中我们是不会使用 Thread 来执行多任务的,而是会使用线程池来执行多任务,这样可以避免线程重复启动和销毁所带来的性能开销,实现代码如下:
// 创建固定线程数的线程池 ExecutorService executorService = Executors.newFixedThreadPool(2); // 任务一 executorService.submit(new Runnable() { @Override public void run() { // do something } }); // 任务二 executorService.submit(new Runnable() { @Override public void run() { // do something } });
那么这时候问题来了,线程池是没有 join() 方法的,那要怎么实现等待呢?
这个时候就要派出我方大将“CountDownLatch”啦。
吾有上将潘凤,可斩华雄... 出场数秒,潘凤...“卒”。
等等导演,我觉得剧情应该是这样的...