Java并发之CountDownLatch的使用和源码解析
来源:互联网 发布:失物招领网站源码 编辑:程序博客网 时间:2024/06/08 08:14
CountDownLatch
构造方法
它在初始化时候,可以通过构造函数新建一个类似于计数器的功能。
public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); }
应用场景:
几个线程在执行多个或者一个任务A后,需要一起开始执行后续的任务B。那么用CountDownLatch,可以很好的帮助实现该功能。
每当有一个线程完成任务,就调用countDown,将计数器减1。
public void countDown() { sync.releaseShared(1); }
已经执行完A的线程,调用await()方法,等待其他计数器的值变0,也就是其他线程执行完毕。
public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); }
代码使用:
import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedException { final CountDownLatch countDownLatch = new CountDownLatch(4); ExecutorService executorService = Executors.newFixedThreadPool(4); for(int i = 0;i<4;i++){ executorService.execute(new Runnable(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"is coming");try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"is running");countDownLatch.countDown();System.out.println(Thread.currentThread().getName()+"is waiting for the other");try {countDownLatch.await();System.out.println(Thread.currentThread().getName()+"after countDownlatch ");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }); }System.out.println(Thread.currentThread().getName()+"outer for circle"); }}
执行结果:
mainouter for circlepool-1-thread-3is comingpool-1-thread-2is comingpool-1-thread-1is comingpool-1-thread-4is comingpool-1-thread-3is runningpool-1-thread-2is runningpool-1-thread-1is runningpool-1-thread-2is waiting for the otherpool-1-thread-3is waiting for the otherpool-1-thread-1is waiting for the otherpool-1-thread-4is runningpool-1-thread-4is waiting for the otherpool-1-thread-3after countDownlatch pool-1-thread-1after countDownlatch pool-1-thread-2after countDownlatch pool-1-thread-4after countDownlatch
源码分析:
CountDownLatch的构造函数(采用的是一种公平锁机制)
CountDownLatch的函数列表
void await():如果当前count大于0,当前线程将会wait,直到count等于0或者中断。PS:当count等于0的时候,再去调用await(),
线程将不会阻塞,而是立即运行。后面可以通过源码分析得到。
boolean await(long timeout, TimeUnit unit):使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
void countDown(): 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
long getCount() :获得计数的数量 //用于debug或者test
String toString() : return super.toString() + "[Count = " + sync.getCount() + "]";
CountDownLatch的数据结构:
await()的分析
AQS:acquireSharedInterruptibly(int arg)
CountDownLatch$Sync:int tryAcquireShared(int acquires)
如果获取共享锁继续调用doAcquireSharedInterruptibly(arg)
如果这里多个线程wait之间没有调用countDown(),线程都在等待。如下图:
setHeadAndPropagate(Node node, int propagate)
isShared()
释放共享锁,通知后面的节点。
compareAndSetWaitStatus(Node,int,int)
看jvm的代码 hotspot-9646293b9637\src\share\vm\runtimeunsafe.cpp
c++:comapreAndSwapInt
atomic.cpp
c++:cmpxchg 根据(update参数来看)代码应该赋值后在比较,但是while比较之后会再一次赋值。
countDown()分析
boolean releaseShared(int arg)
tryReleaseShared(int)
0 0
- Java并发之CountDownLatch的使用和源码解析
- Java并发之CountDownLatch源码分析
- 【JAVA-并发】CountDownLatch用法和源码浅析
- java并发编程中CountDownLatch和CyclicBarrier的使用 - [java]
- Java并发编程之——CountDownLatch的使用
- java并发编程系列之CountDownLatch的使用
- java并发编程之——CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- Java并发编程中CountDownLatch和CyclicBarrier的使用
- Java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- Java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- java并发编程中CountDownLatch和CyclicBarrier的使用
- 2440超详细uboot移植笔记(三)------指定交叉编译链
- JS事件流(事件冒泡和事件捕获)
- DTLS编写样例二(基于DTLSConnector)
- Universal image loader设置图片圆角不显示
- 深入理解JVM——java内存区域与内存溢出异常
- Java并发之CountDownLatch的使用和源码解析
- 【原创】【程序小游戏】迷宫(版本1)
- 产品经理之产品需求文档PRD-全栈工程师熊盼
- HDU2516(斐波那契博弈)
- JBoss 6.4 Eclipse 无法热部署
- 开博客了
- 设计原则学习笔记
- V
- PAT 1006 乙等 (换个格式输出整数) c++