java多线程CountDownLatch
先上一个介绍:https://blog.csdn.net/shihuacai/article/details/8856370
用视频https://www.bilibili.com/video/av81181427 中的一个例子来测试
@Test
public void countdownlatch ()throws InterruptedException {
/*
这个5不能循环,减到0了之后await作用就消失了
*/
CountDownLatch countDownLatch=new CountDownLatch(5);
for(int i=0;i<5;i++){
new Thread(()->{
try{
Thread.sleep(new Double(Math.random()*3000).longValue());
System.out.println(Thread.currentThread().getName()+"玩家准备就绪");
countDownLatch.countDown();//计数点
System.out.println(Thread.currentThread().getName()+"玩家选择英雄");
}catch (InterruptedException e){
e.printStackTrace();
}
}).start();
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"开始游戏");
//Thread.sleep(3000);
}
输出为:
Thread-0玩家准备就绪
Thread-0玩家选择英雄
Thread-2玩家准备就绪
Thread-2玩家选择英雄
Thread-4玩家准备就绪
Thread-4玩家选择英雄
Thread-3玩家准备就绪
Thread-3玩家选择英雄
Thread-1玩家准备就绪
Thread-1玩家选择英雄
main开始游戏
实际上,CountDownLatch阻塞的是主线程而非子线程,这一点要弄清楚。子线程中countDownLatch.countDown();唯一的作用就是将CountDownLatch对象内部的计数器减一,它不能起到阻塞子线程的作用。唯一受到阻塞的是创建完子线程后执行countDownLatch.await();语句的父线程,只有CountDownLatch对象内的计数器减到0之后主线程才能继续执行,而这和子线程的执行无关。
说明这一点最直观的方式是让CountDownLatch的初始参数比线程数小,我们把参数调成5,用10个线程。看看输出是什么:
Thread-4玩家准备就绪
Thread-4玩家选择英雄
Thread-7玩家准备就绪
Thread-7玩家选择英雄
Thread-6玩家准备就绪
Thread-6玩家选择英雄
Thread-5玩家准备就绪
Thread-5玩家选择英雄
Thread-3玩家准备就绪
Thread-3玩家选择英雄
main开始游戏
为什么只有5个子线程执行的结果,剩下的5个子线程去哪里了?别急,我们在主线程的代码末尾加一句sleep语句:
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"开始游戏");
Thread.sleep(3000);
再次执行,结果是:
Thread-7玩家准备就绪
Thread-7玩家选择英雄
Thread-9玩家准备就绪
Thread-9玩家选择英雄
Thread-2玩家准备就绪
Thread-2玩家选择英雄
Thread-6玩家准备就绪
Thread-6玩家选择英雄
Thread-0玩家准备就绪
Thread-0玩家选择英雄
main开始游戏
Thread-5玩家准备就绪
Thread-5玩家选择英雄
Thread-4玩家准备就绪
Thread-4玩家选择英雄
Thread-1玩家准备就绪
Thread-1玩家选择英雄
Thread-3玩家准备就绪
Thread-3玩家选择英雄
Thread-8玩家准备就绪
Thread-8玩家选择英雄
可以看出,之前剩下五个子线程的内容输出不出来,是因为父线程执行完后函数返回了。但是我们知道,父线程和子线程是独立执行的。这是为什么?
其实这是因为我使用的是Junit测试方法,而Junit不支持多线程而已,这个帖子就提到了这一点:在junit单元测试中,当创建了新线程后,单元测试并不会等待主线程下启动的新线程是否执行结束,只要主线程结束完成,单元测试就会关闭,导致主线程中启动的新线程不能顺利执行完.所以剩下的五个线程还没有执行就被销毁了。
换成普通的main方法再试试:
Thread-0玩家准备就绪
Thread-0玩家选择英雄
Thread-5玩家准备就绪
Thread-5玩家选择英雄
Thread-3玩家准备就绪
Thread-3玩家选择英雄
Thread-1玩家准备就绪
Thread-1玩家选择英雄
Thread-9玩家准备就绪
Thread-9玩家选择英雄
main开始游戏
Thread-7玩家准备就绪
Thread-7玩家选择英雄
Thread-8玩家准备就绪
Thread-8玩家选择英雄
Thread-2玩家准备就绪
Thread-2玩家选择英雄
Thread-6玩家准备就绪
Thread-6玩家选择英雄
Thread-4玩家准备就绪
Thread-4玩家选择英雄
Process finished with exit code 0
这回就正常了
那如果CountDownLatch的初始参数比线程数大会发生什么,我们把参数调成10,用5个线程。
Thread-2玩家准备就绪
Thread-2玩家选择英雄
Thread-1玩家准备就绪
Thread-1玩家选择英雄
Thread-0玩家准备就绪
Thread-0玩家选择英雄
Thread-4玩家准备就绪
Thread-4玩家选择英雄
Thread-3玩家准备就绪
Thread-3玩家选择英雄
实际上,虽然子线程都执行完了,程序还是不会停止的,因为CountDownLatch内的计数器不会被减到0,main线程一直处于阻塞状态。
java多线程CountDownLatch的更多相关文章
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- Java多线程-CountDownLatch、CyclicBarrier、Semaphore
上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...
- java多线程 -- CountDownLatch 闭锁
CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...
- java多线程-CountDownLatch
简介 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数 初始化 CountDownLatch.由于调用了 countDown() 方法,所以在当前计数 ...
- java 多线程 CountDownLatch用法
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...
- (转)java 多线程 CountDownLatch用法
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...
- Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger
前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...
- Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例
概要 前面对"独占锁"和"共享锁"有了个大致的了解:本章,我们对CountDownLatch进行学习.和ReadWriteLock.ReadLock一样,Cou ...
- java多线程系列(八)---CountDownLatch和CyclicBarrie
CountDownLatch 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线 ...
随机推荐
- Spark基础和RDD
spark 1. Spark的四大特性 速度快 spark比mapreduce快的两个原因 基于内存 1. mapreduce任务后期在计算的是时候,每一个job的输出结果都会落地到磁盘,后续有其他的 ...
- Linux系统开机显示BusyBox v1.22.1 built-in shell(ash) 解决方法
BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件.BusyBox 包含了一些简单的工具,例如ls.cat和echo等等,还包含了一些更大.更复杂的工具,例grep.find.mou ...
- java设计模式学习笔记--浅谈设计模式
设计模式的目的 编写软件的过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战.设计模式为了让程序具有更好的 1.代码重用性(即:相同功能的代码,不用多次编写) ...
- IO流学习之综合运用(文件复制)
通过File.字节流.字节流缓冲区实现文件复制 需求: 1.用File类读取指定文件File下的所有文件(包括Copy文件夹内的所有文件) 2.将所有文件复制到指定文件FileCopy夹下 需求分析: ...
- 【感知机模型】手写代码训练 / 使用sklearn的Perceptron模块训练
读取原始数据 import pandas as pd import numpy as np in_data = pd.read_table('./origin-data/perceptron_15.d ...
- javaweb实现注册页面(数据库连接以及ajax验证)
先放效果图 可实现js实时验证 可实现ajax实时验证注册信息是否存在 页面实现要求 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求 ...
- jquery的封装与对象学习
1.封装学习 /// <reference path="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" /> ...
- sql注入常见绕过技巧
参考链接:https://blog.csdn.net/huanghelouzi/article/details/82995313 https://www.cnblogs.com/vincy99/p/9 ...
- sqli-labs5-10(全程sqlmap)
sqlmap注入教程:https://www.cnblogs.com/ichunqiu/p/5805108.html 前五关直接可以用默认的sqlmap语法跑: python sqlmap.py -u ...
- sqli-labs less-17 --> less-20
Less-17 (报错盲注) 参考资料1:https://www.cnblogs.com/AmoBlogs/p/8673748.html