java:用CountDownLatch.await替代Object.wait实现线程阻塞/唤醒
来源:互联网 发布:大数据和云计算的关系 编辑:程序博客网 时间:2024/06/16 00:55
线程之间经常需要一定的同步,比如线程A需要线程B的部分运算结果,但又不必等到线程B把所有的结果都算出来,否则A就要待太长时间。
下面这个例子就是这个应用场景,主线程需要等待子线程从数据库中加载记录,但是子线程把所有的记录都加载完要花挺长时间。
而实际上,主线程最开始只需要一条记录就可以继续自己的后续动作了。怎么办呢?下面的代码利用传统的Object.wait()/nofity()方法来实现:
public void openSource() { // 创建一个初值为1的倒数计数器对象作为通知对象 Object notifier=new Object(); // 启动新线程用于长时间的加载任务 new Thread(new Runnable() { @Override public void run() { boolean isNotified=false; try { int index = 0; while (true) { { // 加载数据。。。。 } // 加载第一条记录后,唤醒等待线程 if (1 == ++index) { synchronized (notifier){ notifier.notify(); isNotified=true; } } } } finally { //循环结束,不论有没有加载到数据记录,都执行唤醒, //以确保notify无论如何都会被执行一次,否则等待线程会一直阻塞 synchronized (notifier){ if(!isNotified) notifier.notify(); } } } }).start(); synchronized (notifier){ try { // 启动子线程后立即阻塞, 等待被子线程唤醒 notifier.wait(); } catch (InterruptedException e) {} } // 确保子线程加载了第一记录后,主线程继续自己的工作。。。。 }
话说,用Object.wait()/notify()倒是挺直观,但是,这synchronized同步块代码写起来实在有点啰嗦,我是个一行代码都不想多写的懒人。
就在想这代码能不能 看着更简单点?
于是想到了java.util.concurrent包下的CountDownLatch,
这是个好东西,顾名思义,它实现了一个多线程环境下倒数计数器锁,当计数器倒数到0时,唤醒阻塞的线程,允许多个线程同时对计数器减1,用在这里实在大材小用了。不过管它呢,方便就成啊。
于是前面的代码就被我用CountDownLatch改造成下面这样:
public void openSource() { // 创建一个初值为1的倒数计数器锁 CountDownLatch notifier=new CountDownLatch(1); new Thread(new Runnable() { @Override public void run() { try { int index = 0; while (true) { { // 加载数据。。。。 } if (1 == ++index) { // 计数减1,唤醒等待线程 notifier.countDown(); } } } finally { // 线程结束之前再执行一次唤醒动作 notifier.countDown(); } } }).start(); try { // 启动子线程后立即阻塞, 等待被倒数计数器锁唤醒 notifier.await(); } catch (InterruptedException e) {} }
相比前面的代码,finally{}代码块中没有再判断是否已经执行过唤醒动作,为什么呢,因为countDown当计数已经归0的时候什么也不做,所以就算多执行一次countDown也完全不影响程序的逻辑。
没有烦人的synchronized同步块代码块后,代码是不是看起来简洁一点点呢?
当然相比原始的wait/nofity,CountDownLatch的实现是经过高度封装的代码,最终它也是用wait/nofity来实现的,但逻辑更复杂,所以性能上有多少影响我并不清楚,因为我的应用环境是在程序初始化的时候,并不是高频调用,所以我并不太关注这个。
- java:用CountDownLatch.await替代Object.wait实现线程阻塞/唤醒
- Java线程唤醒与阻塞
- Java线程唤醒与阻塞
- java线程阻塞与唤醒
- Java线程唤醒与阻塞
- Java线程唤醒与阻塞
- Java线程唤醒与阻塞
- java线程之间的调度使用wait/notify,await/single,LinkBlockingQuene实现
- JAVA 线程等待唤醒,wait and notify
- Java并发编程之CountDownLatch,CyclicBarrier实现一组线程相互等待、唤醒
- 多线程之Java线程阻塞与唤醒
- 多线程之Java线程阻塞与唤醒
- 线程阻塞与唤醒
- 线程阻塞与唤醒
- 线程通信(子线程运行10次,主线程运行100次,如此循环50次)[用condition替代wait,notify等待和唤醒操作]
- Java-线程$等待唤醒机制(wait,notify)
- Java线程之等待wait唤醒notify示例(一)
- java多线程学习之线程通信-wait()等待 notify()唤醒
- maven的pom报plugins的解决方法
- Java_Ant详解
- 一句printf搞定一个数组的矩阵输出。
- Java动态绑定与静态绑定
- SSH框架之Hibernate的主配置文件
- java:用CountDownLatch.await替代Object.wait实现线程阻塞/唤醒
- 细节成就未来(结构化数组)
- python菜鸟
- 【从零开始学习MySql数据库】(1)建表与简单查询
- 英文歌曲初恋《heartbeats》 心跳
- Linux下磁盘的挂载与卸载
- HEVC码率控制(二):从compressGOP()到compressSlice()
- Android----按钮单击事件的四种写法
- centos7 网卡名字改为eth0