当前位置:网站首页>JUC并发包—CountDownLatch
JUC并发包—CountDownLatch
2022-07-15 20:17:00 【#小苏打】
目录
什么是CountDownLatch
CountDownLatch是JDK提供的一个同步工具,它可以让一个或多个线程等待,一直等到其他线程中执行完成一组操作。可以用作线程同步
CountDownLatch的方法
countDown方法
CountDownLatch在初始化时,需要给构造器指定用给定一个整数作为计数器。
CountDownLatch countDownLatch = new CountDownLatch(10);当调用
countDown方法时,计数器会被减1
await方法
当调用
await方法时,如果计数器大于0时,线程会被阻塞,一直到计数器被countDown方法减到0时,线程才会继续执行。计数器是无法重置的,当计数器被减到0时,调用await方法都会直接返回。
例子
实现类型LOL十个玩家加载完成后,开始游戏
public class Countdown_Latch {
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(10);
CountDownLatch countDownLatch = new CountDownLatch(10);
String[] all = new String[10];
Random r = new Random();
for (int j = 0; j <10 ; j++) {
int a = j;
pool.submit(()->{
for (int i = 0; i <=100 ; i++) {
all[a] = i+"%";
try {
Thread.sleep(r.nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("\r"+Arrays.toString(all));
}
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println("\n"+"游戏开始");
pool.shutdown();
}
}//输出结果
[100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%]
游戏开始
CountDownLatch的实现原理
CountDownLatch有一个内部类叫做Sync,它继承了AbstractQueuedSynchronizer类,其中维护了一个整数
state,并且保证了修改state的可见性和原子性。
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
countDown方法源码
在 countDown方法中,只调用了Sync实例的releaseShared方法
public void countDown() {
sync.releaseShared(1);
}
其中的releaseShared方法,先对计数器进行减1操作,如果减1后的计数器为0,唤醒被await方法阻塞的所有线程。
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) { //对计数器进行减一操作
doReleaseShared(); //如果计数器为0,唤醒被await方法阻塞的所有线程
return true;
}
return false;
}
await方法源码
在await方法中,只调用了Sync实例的acquireSharedInterruptibly方法
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
其中acquireSharedInterruptibly方法,判断计数器是否为0,如果不为0则阻塞当前线程
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0) //判断计数器是否为0
doAcquireSharedInterruptibly(arg);//如果不为0则阻塞当前线程
}
边栏推荐
猜你喜欢
随机推荐
数字孪生电网发展历程
Linux 离线安装 mysql 5.7
Unity shader - cginclude file cginc
408天勤第八章排序课内代码合集
Apache configuration
Nest 框架
数字孪生给水库装上“智慧大脑”
要想不踩SaaS那些坑,得先了解“SaaS架构”
模拟卷Leetcode【普通】1823. 找出游戏的获胜者
Codeforces Round #802 C. Helping the Nature
mysql: command not found 找不到mysql命令
2022年上半年新晋独角兽40家,30%都被红杉中国投过了
华为云服务器云数据库创建只读过程
Codeforces Global Round 21 C. Fishingprince Plays With Array
Codeforces Global Round 21 A. NIT orz!
STM32F030外部中断配置
Can communication (1) - physical layer of CAN communication
小程序媒体组件-1
Stm32f030 external interrupt configuration
Codeforces Round #802 B. Palindromic Numbers









![2022-7-15 Leetcode 151. Reverse the words in the string - [split from back to front]](/img/46/6bb2c4e59b2328482b92619783f0bd.png)