- 浏览: 71271 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
须等待:
强烈同意。。。。这个编辑器简直太不好用了!
对于在Ubuntu下的Eclipse上安装SVN客户端插件Subclipse的补充 -
nudtgk2000:
flysnail 写道 思路挺好,
谢谢鼓励,还是初学者,不 ...
重写CountDownLatch以实现线程状态监视 -
flysnail:
思路挺好,:)
重写CountDownLatch以实现线程状态监视
需求:管理线程需要及时知道工作线程全部处于等待状态,并满足等待条件让他们恢复运行。
思想:有一种方法是“心跳方法”,让工作线程定时向管理线程“报到”。而这里我想通过并发的状态计数来实现状态监视。jdk提供有两种并发的状态计数:java.util.concurrent.CountDownLatch 和 java.util.concurrent.CyclicBarrier 。CountDownLatch 初始化后,工作线程调用countDown方法,计数减为0以前,调用await方法的其他线程会一直阻塞。它适用于一个或几个其他线程等待一组线程都经过某点的情形,但有一个局限,即它是一次性的能重置。CyclicBarrier 可以重置,但它只适用于一组线程分别到达某点后互相等待以实现步调一致的情形。(见JDK 1.6)
于是我考虑修改CountDownLatch 类,使其支持重置,以胜任连续监视的需求。
代码如下:
修改后的新计数器类:ResetableCountDownLatch
import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.*; public class ResetableCountDownLatch { /** * Synchronization control For ResetableCountDownLatch. * Uses AQS state to represent count. */ private static final class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 4982264981922014374L; Sync(int count) { setCount(count); } void setCount(int count) { setState(count); } int getCount() { return getState(); } public int tryAcquireShared(int acquires) { return getState() == 0? 1 : -1; } public boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } } private final Sync sync; /** * Constructs a {@code ResetableCountDownLatch} initialized with the given count. * * @param count the number of times {@link #countDown} must be invoked * before threads can pass through {@link #await} * @throws IllegalArgumentException if {@code count} is negative */ public ResetableCountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } public void countDown() { sync.releaseShared(1); } public long getCount() { return sync.getCount(); } // 增加了这个方法 public void setCount(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); sync.setCount(count); } public String toString() { return super.toString() + "[Count = " + sync.getCount() + "]"; }
测试用例:
public static void main(String[] args) { // 初始化计数器,本例有3个工作线程 ResetableCountDownLatch latch = new ResetableCountDownLatch(3); ThreadGroup tg = new ThreadGroup(""); class RunBody implements Runnable { ResetableCountDownLatch latch; RunBody(ResetableCountDownLatch latch) { this.latch = latch; } @Override public void run() { System.out.println(Thread.currentThread().getName() + " start."); for(int i=0; i<Thread.currentThread().getId(); ++i) { try { Thread.sleep(1000); // 在wait前递减计数器 synchronized(this) { System.out.println(Thread.currentThread().getName() + " wait " + (i+1) + "time(s)"); latch.countDown(); this.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " continue."); } // 线程结束前也要countDown “告知”监视线程 System.out.println(Thread.currentThread().getName() + " finish."); latch.countDown(); } } RunBody threadBody = new RunBody(latch); for(int i=0; i<3; ++i) { new Thread(tg, threadBody).start(); } while(true) { try { latch.await(); // 需要判断工作线程是否全结束了 if(0==tg.activeCount()) { break; } System.out.println("Main: there are " + tg.activeCount() + " live threads all waiting"); synchronized(threadBody) { // 重置计数器,注意:是存活的工作线程数 latch.setCount(tg.activeCount()); System.out.println("Main: wake them up."); threadBody.notifyAll(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Main: All threads finished."); }
测试输出:
Thread-1 start. Thread-2 start. Thread-0 start. Thread-2 wait 1time(s) Thread-0 wait 1time(s) Thread-1 wait 1time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-1 continue. Thread-2 continue. Thread-0 continue. Thread-2 wait 2time(s) Thread-0 wait 2time(s) Thread-1 wait 2time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-1 continue. Thread-0 continue. Thread-2 continue. Thread-2 wait 3time(s) Thread-1 wait 3time(s) Thread-0 wait 3time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-0 continue. Thread-1 continue. Thread-2 continue. Thread-2 wait 4time(s) Thread-0 wait 4time(s) Thread-1 wait 4time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-1 continue. Thread-2 continue. Thread-0 continue. Thread-1 wait 5time(s) Thread-2 wait 5time(s) Thread-0 wait 5time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-0 continue. Thread-2 continue. Thread-1 continue. Thread-0 wait 6time(s) Thread-1 wait 6time(s) Thread-2 wait 6time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-2 continue. Thread-1 continue. Thread-0 continue. Thread-2 wait 7time(s) Thread-1 wait 7time(s) Thread-0 wait 7time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-0 continue. Thread-1 continue. Thread-2 continue. Thread-0 wait 8time(s) Thread-1 wait 8time(s) Thread-2 wait 8time(s) Main: there are 3 live threads all waiting Main: wake them up. Thread-1 continue. Thread-2 continue. Thread-0 continue. Thread-0 finish. Thread-2 wait 9time(s) Thread-1 wait 9time(s) Main: there are 2 live threads all waiting Main: wake them up. Thread-2 continue. Thread-1 continue. Thread-1 finish. Thread-2 wait 10time(s) Main: there are 1 live threads all waiting Main: wake them up. Thread-2 continue. Thread-2 finish. Main: All threads finished.
发表评论
-
【转】常用的系统属性
2012-11-21 17:02 745获取类文件所在的绝对路径 写道 "Jav ... -
用Log4j实现线程独立日志
2012-11-04 22:53 8072需求: 在一个项目里,我使用Log4j生成日志, ... -
byte型检查
2012-09-09 21:14 762byte b; //... ... // 范围检查,确保只 ... -
【转】Dom4j的使用(全而好的文章)
2012-08-07 15:09 908java解析xml汇总, 结论就是Dom4j比其他几种好 ... -
【转】正则表达式的一些资料
2012-08-07 15:07 821JAVA 正则表达式 (超详细)http://blog.csd ... -
【转摘】Exception in thread "main" java.lang.OutOfMemoryError: Java heap space解决方法
2012-08-04 18:02 14852摘自http://hi.baidu.com/61919 ... -
【转】java解析xml汇总
2012-07-31 20:53 16java解析xml汇总 -
java.io.InputStream.mark(int readlimit) 方法的个人理解
2012-05-16 16:04 0在马士兵java课程的IO这一章[1]中遇到 java.io ... -
马士兵课程笔记(续7) —— 流
2012-03-20 18:51 0Java 流式输入/输出原理 ... -
马士兵课程笔记(续6)
2012-03-18 18:31 1209容器 概念 Java API 所提供的用于在程序中 ... -
走了一段值得的弯路
2012-03-16 21:27 1013class C { int i; S ... -
马士兵课程笔记(续5)
2012-03-09 19:28 1411常用类 字符串相关类(String, StringBuff ... -
马士兵课程笔记(续4)
2012-02-28 21:58 1083数组 数组可以看成是多个相同类型数据组合,对这些数据的统一 ... -
马士兵课程笔记(续3)
2012-02-22 16:47 1434抽象类 关键字abstract 含有抽象方法的类必须声明 ... -
马士兵课程笔记(续2)
2012-01-03 15:50 1090J2SDK中主要的包介绍 位置%JAVAHOME%\jr ... -
马士兵课程笔记
2011-11-14 07:47 1223J2EE框架 EJB (Enterprise Ja ... -
JAVA中 @Override 的作用(转)
2011-10-22 22:44 2532<!-- @pa ...
相关推荐
利用 CountDownLatch 类实现线程同步,而不用回调机制。详见我的博文 http://blog.csdn.net/kroclin/article/details/37956949
mybaits 多线程 实现数据批量插入 (运用CountDownLatch实现闭锁) 1、mybatis批处理 2、数据分批量查询 3、数据分批量插入
主要为大家详细介绍了使用CountDownLatch等待多线程全部执行完成,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了Java中CountDownLatch进行多线程同步详解及实例代码的相关资料,需要的朋友可以参考下
NULL 博文链接:https://cpjsjxy.iteye.com/blog/2272451
主要介绍了如何使用CountDownLatch同步java多线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
CountDownLatch可以实现一个线程等待多个线程、多个线程等待一个线程、多个线程等待多个线程(这里不涉及)。 我们首先来看看怎么实现一个线程等待多个线程吧。 工厂中,对产品需要进行质检,5个工人进行检查,所有...
在Java中和ReadWriteLock.ReadLock一样,CountDownLatch的本质也是一个"共享锁",这里我们就来详解Java多线程编程中CountDownLatch阻塞线程的方法:
利用CountDownLatch实现基于netty的"BIO"。仅供学习。也可关注公众号“duomi88”获取下载地址。
具有countDownLatch的线程同步模式
实现多线程任务的同步 3.1 场景介绍 3.2 使用CountDownLatch实现同步 主线程等待多个线程完成 4.1 场景介绍 4.2 使用CountDownLatch实现等待 CountDownLatch的其他应用场景 5.1 倒计时计时器 5.2 同时开始任务 5.3 ...
主要介绍了JAVA多线程CountDownLatch的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
JUC(Java Util Concurrent)是Java中用于并发编程的工具包,提供了一组接口和类,用于...并发工具类:JUC提供了一些并发编程的工具类,如Semaphore、CountDownLatch、CyclicBarrier等,可以实现线程间的协作和同步。
《java并发编程》中CountDownLatch和CyclicBarrier用法实例大全,几乎包含了所有重要的用法
目录 CountDownLatch是什么? CountDownLatch如何工作? 在实时系统中的应用场景 应用范例 常见的面试题 代码样例
主要介绍了Java线程并发工具类CountDownLatch原理及用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
递减锁存器CountDownLatch的使用以及注意事项!
CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复...
在网上找的一个CountDownLatch的学习demo,感觉很不错,就摘抄过来了
CountDownLatch与thread.join()的区别