JUC包下CountDownLatch学习笔记
2024-08-30 22:48:07
CountDownLatch的作用是能使用多个线程进来之后,且线程任务执行完毕之后,才执行,
闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状态也就不能变了,只能是打开状态。也就是说闭锁的状态是一次性的,它确保在闭锁打开之前所有特定的活动都需要在闭锁打开之后才能完成。
与CountDownLatch第一次交互是主线程等待其它的线程,主线程必须在启动其它线程后立即调用await方法,这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。
其他的N个线程必须引用闭锁对象,因为他们需要通知CountDownLatch对象,他们已经完成了各自的任务,这种机制就是通过countDown()方法来完成的。每调用一次这个方法,在构造函数中初始化的count值就减1,所以当N个线程都调用了这个方法count的值等于0,然后主线程就能通过await方法,恢复自己的任务。
这里的主线程是相对的概念,需要根据CountDownLatch创建的场景分析。
package com.cxy.cyclicBarrier; import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* Created by Administrator on 2017/4/10.
*/
public class CountDownDemo { private static final Random random = new Random();
// 用于判断发令之前运是否已经进入准备状态,需要等待10个准备就绪,占有锁,等待10个完成,释放锁。
private static CountDownLatch readyLatch = new CountDownLatch();
// 用于判断裁判是否已经发令,占有锁,等待裁判发令完成,释放锁
private static CountDownLatch startLatch = new CountDownLatch(); public static void main(String[] args) { // 用于判断发令之前是否已经进入准备状态,需要等待10个准备就绪,占有锁,等待10个完成,释放锁。
// CountDownLatch readyLatch = new CountDownLatch(SPORTSMAN_COUNT);
// 用于判断是否已经发令,占有锁,等待裁判发令完成,释放锁
// CountDownLatch startLatch = new CountDownLatch(1); // 启动10个线程,也就是10个,做准备工作
for (int i = ; i < ; i++) {
Thread t = new Thread(new MyTask((i + ) + "号", readyLatch, startLatch));
t.start();
}
// 当前在其他准备就绪前一直等待,也就是说等readyLatch倒数计数器为0之前一直等待
try {
readyLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
} // 裁判发令,释放锁
startLatch.countDown(); System.out.println("老大:所有准备完毕,开始..."); } static class MyTask implements Runnable { private Lock lock = new ReentrantLock(); private CountDownLatch ready;
private CountDownLatch start;
private String name; public MyTask(String name, CountDownLatch ready, CountDownLatch start) {
this.ready = ready;
this.start = start;
this.name = name;
} @Override
public void run() {
lock.lock();
try { // 1. 准备就绪的逻辑,准备readyTime秒
int readyTime = random.nextInt();
System.out.println(name + ":我需要" + readyTime + "秒的时间准备。");
try {
Thread.sleep(readyTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "我已经准备完毕!");
// 释放锁readyLatch-1,表示一个已经就绪
ready.countDown();
try {
// 等待发开始命令
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":行动...");
} catch (Exception e) {
// TODO: handle exception
} finally {
lock.unlock();
} } }
}
执行结果:
1号:我需要365秒的时间准备。
2号:我需要454秒的时间准备。
5号:我需要938秒的时间准备。
3号:我需要967秒的时间准备。
7号:我需要878秒的时间准备。
6号:我需要540秒的时间准备。
9号:我需要552秒的时间准备。
10号:我需要281秒的时间准备。
4号:我需要951秒的时间准备。
8号:我需要696秒的时间准备。
10号我已经准备完毕!
1号我已经准备完毕!
2号我已经准备完毕!
6号我已经准备完毕!
9号我已经准备完毕!
8号我已经准备完毕!
7号我已经准备完毕!
5号我已经准备完毕!
4号我已经准备完毕!
3号我已经准备完毕!
老大:所有准备完毕,开始...
2号:行动...
6号:行动...
1号:行动...
9号:行动...
8号:行动...
7号:行动...
10号:行动...
5号:行动...
4号:行动...
3号:行动... Process finished with exit code
countdownLatch也是也实现cycliBarrier珊拦结构,不过需要使用lock锁
最新文章
- activity与fragment之间传递数据
- 彻底理解nth-child和nth-of-type的区别。
- Activity生命周期(深入理解)
- matlab中findstr,strfind,strcmp,strncmp区别与联系
- iOS初级数据持久化 沙盒机制 归档与反归档
- Xcode 7安装KSImageNamed失败解决方法
- python Eve RESTFul 尝试笔记
- JavaScript 输入验证器工具
- netperf 而网络性能测量
- 关于Java String对象创建的几点疑问
- ${pageContext.request.contextPath}的作用
- hdu 5532
- jQuery图片轮播(一)轮播实现并封装
- VS复制文件到输出目录
- springmvc文件上传下载简单实现案例(ssm框架使用)
- 阅读OReilly.Web.Scraping.with.Python.2015.6笔记---BeautifulSoup---findAll
- python特殊的数据类型
- weblogic 12C集群环境下的session复制
- 关于Unity中新版动画系统的使用
- logging 的配置和使用
热门文章
- 手动去除uTorrent中广告的步骤(V3.4.9依然有效)
- java基础之多线程二:多线程实现方式
- linux下配置eclipse环境
- Luogu 2868 [USACO07DEC]观光奶牛Sightseeing Cows
- XMLHttpRequest实现Ajax异步请求
- 【原创】boost::recursive_mutex请小心使用
- KMP算法细讲(豁然开朗)
- LibreOJ 6001 太空飞行计划(最大流)
- 数据库去重与join连表
- c# Include 与 用户控件