CountDownLatch使用countDown方法来触发其他等待线程再执行的问题
来源:互联网 发布:打击电信网络诈骗视频 编辑:程序博客网 时间:2024/05/21 10:56
对于CountDownLatch这个类之前了解过, 根据java 文档,其作用如下:
A synchronization aid that allows one or more threads to wait until
a set of operations being performed in other threads completes.
下面应该是常规用法:
CountDownLatch works by having a counter initialized with number of threads,
which is decremented each time a thread complete its execution.
When count reaches to zero, it means all threads have completed their execution,
and thread waiting on latch resume the execution.
其步骤如下:
1. Main thread start
2. Create CountDownLatch with count N for N threads
3. Create and start N threads
4. Main thread wait on latch - await()
5. N threads completes there tasks are returns -countDown() to decrement count
6. Main thread resume execution -count == 0
还有一种用法:
1. Main thread start
2. Create CountDownLatch with count 1 for N threads
3. Create and start N threads
4. N threads are waiting for latch with 1 count -await()
5. Main thread count down - countDown() to decrement count to 0
6. Main thread resume execution
在第二种用法中,第5步执行前应该有个等待的时间,让所有的线程都
执行到await。
比如下面的例子,用ExecutorService的submit来新建和启动线程,线程
在被submit 之后就已经执行了,而且主线程也会继续执行,很有可能有些
线程没有执行到await, 主线程就已经countDown了。
package thread;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
/**
* 利用两个 CountDownLatch 来计算10人跑步成绩平均值:
*
* 1) beginLatch 计数器为1, 在每个runner线程中调用beginLatch的await方法,
* 等待主线程中beginLatch的countDown方法调用然后一起执行;
*
* 2) endLatch 计数器为10, 在主线程中调用endLatch的await方法,等待每个runner线程中调用endLatch的countDown * 方法,将10递减为0后计算总成绩的平均值.
*
*/
public class TestCountDownLatch {
public static void main(String[] args) throws Exception {
//发令枪只响一次
CountDownLatch beginLatch = new CountDownLatch(1);
//有10个运动员
int num = 10;
CountDownLatch endLatch = new CountDownLatch(num);
//每个运动员一个赛道
ExecutorService es = Executors.newFixedThreadPool(num);
List<Future<Integer>> futureList = new ArrayList<>();
for (int i = 0; i < num; i++) {
futureList.add(es.submit(new Runner(beginLatch, endLatch)));
}
// TimeUnit.MILLISECONDS.sleep(500); //预备时间, 多长时间能让运动员都准备好?
System.out.println("Run");
//发令枪响,开始跑步
beginLatch.countDown();
//等待所有人跑完全程
endLatch.await();
int sum = 0;
for (Future<Integer> future : futureList) {
sum += future.get(); //计算总成绩
}
System.out.println("Average score is: "+ sum / num);
es.shutdown();
}
}
class Runner implements Callable<Integer> {
CountDownLatch begin;
CountDownLatch end;
public Runner(CountDownLatch begin, CountDownLatch end) {
this.begin = begin;
this.end = end;
}
@Override
public Integer call() throws Exception {
long threadId = Thread.currentThread().getId();
//跑步的成绩
int score = new Random().nextInt(25);
//等待发令枪响
System.out.println(threadId + " is ready");
begin.await();
System.out.println(threadId + " is running...");
//跑步中
// TimeUnit.MILLISECONDS.sleep(500);
//跑步者已经跑完全程
end.countDown();
System.out.println(threadId + " is finished");
return score;
}
}
如果注释掉主线程中下面的这一段代码:
TimeUnit.MILLISECONDS.sleep(500); //预备时间, 多长时间能让运动员都准备好?
那么可能会出现抢跑的结果:
10 is ready
13 is ready
Run
14 is ready
14 is running...
14 is finished
11 is ready
11 is running...
11 is finished
15 is ready
15 is running...
15 is finished
17 is ready
17 is running...
17 is finished
19 is ready
19 is running...
19 is finished
12 is ready
16 is ready
16 is running...
16 is finished
12 is running...
12 is finished
10 is running...
10 is finished
13 is running...
13 is finished
18 is ready
18 is running...
18 is finished
Average score is: 11
如果不注释掉主线程中的等待时间,那么结果显示为都准备好了才跑:
11 is ready
15 is ready
17 is ready
13 is ready
19 is ready
10 is ready
14 is ready
18 is ready
12 is ready
16 is ready
Run
11 is running...
11 is finished
15 is running...
15 is finished
17 is running...
17 is finished
13 is running...
19 is running...
19 is finished
13 is finished
10 is running...
10 is finished
14 is running...
14 is finished
18 is running...
18 is finished
12 is running...
12 is finished
16 is running...
16 is finished
A synchronization aid that allows one or more threads to wait until
a set of operations being performed in other threads completes.
下面应该是常规用法:
CountDownLatch works by having a counter initialized with number of threads,
which is decremented each time a thread complete its execution.
When count reaches to zero, it means all threads have completed their execution,
and thread waiting on latch resume the execution.
其步骤如下:
1. Main thread start
2. Create CountDownLatch with count N for N threads
3. Create and start N threads
4. Main thread wait on latch - await()
5. N threads completes there tasks are returns -countDown() to decrement count
6. Main thread resume execution -count == 0
还有一种用法:
1. Main thread start
2. Create CountDownLatch with count 1 for N threads
3. Create and start N threads
4. N threads are waiting for latch with 1 count -await()
5. Main thread count down - countDown() to decrement count to 0
6. Main thread resume execution
在第二种用法中,第5步执行前应该有个等待的时间,让所有的线程都
执行到await。
比如下面的例子,用ExecutorService的submit来新建和启动线程,线程
在被submit 之后就已经执行了,而且主线程也会继续执行,很有可能有些
线程没有执行到await, 主线程就已经countDown了。
package thread;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
/**
* 利用两个 CountDownLatch 来计算10人跑步成绩平均值:
*
* 1) beginLatch 计数器为1, 在每个runner线程中调用beginLatch的await方法,
* 等待主线程中beginLatch的countDown方法调用然后一起执行;
*
* 2) endLatch 计数器为10, 在主线程中调用endLatch的await方法,等待每个runner线程中调用endLatch的countDown * 方法,将10递减为0后计算总成绩的平均值.
*
*/
public class TestCountDownLatch {
public static void main(String[] args) throws Exception {
//发令枪只响一次
CountDownLatch beginLatch = new CountDownLatch(1);
//有10个运动员
int num = 10;
CountDownLatch endLatch = new CountDownLatch(num);
//每个运动员一个赛道
ExecutorService es = Executors.newFixedThreadPool(num);
List<Future<Integer>> futureList = new ArrayList<>();
for (int i = 0; i < num; i++) {
futureList.add(es.submit(new Runner(beginLatch, endLatch)));
}
// TimeUnit.MILLISECONDS.sleep(500); //预备时间, 多长时间能让运动员都准备好?
System.out.println("Run");
//发令枪响,开始跑步
beginLatch.countDown();
//等待所有人跑完全程
endLatch.await();
int sum = 0;
for (Future<Integer> future : futureList) {
sum += future.get(); //计算总成绩
}
System.out.println("Average score is: "+ sum / num);
es.shutdown();
}
}
class Runner implements Callable<Integer> {
CountDownLatch begin;
CountDownLatch end;
public Runner(CountDownLatch begin, CountDownLatch end) {
this.begin = begin;
this.end = end;
}
@Override
public Integer call() throws Exception {
long threadId = Thread.currentThread().getId();
//跑步的成绩
int score = new Random().nextInt(25);
//等待发令枪响
System.out.println(threadId + " is ready");
begin.await();
System.out.println(threadId + " is running...");
//跑步中
// TimeUnit.MILLISECONDS.sleep(500);
//跑步者已经跑完全程
end.countDown();
System.out.println(threadId + " is finished");
return score;
}
}
如果注释掉主线程中下面的这一段代码:
TimeUnit.MILLISECONDS.sleep(500); //预备时间, 多长时间能让运动员都准备好?
那么可能会出现抢跑的结果:
10 is ready
13 is ready
Run
14 is ready
14 is running...
14 is finished
11 is ready
11 is running...
11 is finished
15 is ready
15 is running...
15 is finished
17 is ready
17 is running...
17 is finished
19 is ready
19 is running...
19 is finished
12 is ready
16 is ready
16 is running...
16 is finished
12 is running...
12 is finished
10 is running...
10 is finished
13 is running...
13 is finished
18 is ready
18 is running...
18 is finished
Average score is: 11
如果不注释掉主线程中的等待时间,那么结果显示为都准备好了才跑:
11 is ready
15 is ready
17 is ready
13 is ready
19 is ready
10 is ready
14 is ready
18 is ready
12 is ready
16 is ready
Run
11 is running...
11 is finished
15 is running...
15 is finished
17 is running...
17 is finished
13 is running...
19 is running...
19 is finished
13 is finished
10 is running...
10 is finished
14 is running...
14 is finished
18 is running...
18 is finished
12 is running...
12 is finished
16 is running...
16 is finished
Average score is: 7
但是这个等待时间不好确定. 一般可能会设置的超过需要的时间很多。
文中代码出自 《编写高质量代码改善Java程序的151个建议》
参考文章:
https://howtodoinjava.com/core-java/multi-threading/when-to-use-countdownlatch-java-concurrency-example-tutorial/
阅读全文
0 0
- CountDownLatch使用countDown方法来触发其他等待线程再执行的问题
- 进阶篇:等待多个子线程完毕再执行主线程的方法之CountDownLatch(十二)
- CountDownLatch实现主线程等待所有子线程运行结束后再继续执行的实现
- CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
- JAVA多线程—CountDownLatch-一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
- 关于使用CyclicBarrier使主线程等待子线程执行完之后再向下执行的问题
- Java主线程等待子线程执行完毕-CountDownLatch
- Java主线程等待子线程执行完毕-CountDownLatch
- 【CountDownLatch实例】主线程等待其它线程执行完毕
- Java主线程等待子线程执行完毕-CountDownLatch
- 代码详解の使用CountDownLatch解决面试问题:T1和T2线程执行计算,T3线程计算结果的统计
- CountDownLatch 控制多线程 让多个线程执行完后再依次做其他的
- 通过FutureTask来实现阻塞当前线程等待其他线程处理的结果
- java使用CountDownLatch实现线程顺序执行
- Java多线程执行,主程序等待其他线程执行完成
- 设置主线程等待子线程执行的方法
- java利用CountDownLatch来制定线程执行顺序
- CountDownLatch 线程工具的使用
- Wannafly挑战赛1 A-DP
- webstorm 的es6设置之后还是出现红线的解决方式
- springmvc mvc:view-controller使用
- 实验四顺序栈的实现
- ABP学习:领域层创建实体(使用MySql数据库)
- CountDownLatch使用countDown方法来触发其他等待线程再执行的问题
- android AIDL,跨进程通讯
- 为什么Java工具类方法为静态类
- memcache和memcached的区分
- java设计模式---装饰者设计模式
- EDW与维度模型间的抉择
- 集群时间点同步及完全分布式搭建
- 嵌入式开发(ARM9)学习笔记(八)-NFS与TFTP服务器配置
- BZOJ 1562: [NOI2009]变换序列 【二分图匹配】【匈牙利】