CountDownLatch在多线程程序中的应用
一.CountDownLatch介绍
CountDownLatch是JDK1.5之后引入的,存在于java.util.concurrent包下,能够使一个线程等待其他线程完成动作后再执行。
构造方法:
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
主要方法:
countDown()方法每调用一次,计数器减1
await()方法使当前线程处于阻塞状态,知道计数器值为0
二.CountDownLatch使用
package com; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger; /**
* CountDownLatch测试
*/
class myThread<T> extends Thread {
CountDownLatch countDownLatch;
Map map;
//构造函数,传入的是Map
public myThread(CountDownLatch countDownLatch, Map map) {
this.countDownLatch = countDownLatch;
this.map = map;
}
public void run() {
map.put(Thread.currentThread().getName(),new Object());
countDownLatch.countDown();//线程执行一次就countDown计数器减少1
}
} public class TestThreadAndCollection {
public static void main(String[] args) throws InterruptedException {
//表示测试100次
for (int i = 0; i < 100; i++) {
test();
}
} public static void test() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2000);
//使用HashMap,这是线程不安全的
Map<String ,Object> hashMap = new HashMap();
//使用ConcurrentHashMap,线程安全的
//Map<String ,Object> concurrentHashMap = new ConcurrentHashMap();
//两个for循环,2000个线程
for (int i = 0; i < 1000; i++) {
//多线程HashMap测试
//myThread mThread = new myThread(latch, hashMap);
//多线程concurrentHashMap测试
myThread mThread = new myThread(latch, hashMap);
mThread.start();
}
for (int i = 0; i < 1000; i++) {
myThread mThread = new myThread(latch, hashMap);
mThread.start();
}
//等待当前所有子线程执行完,这里也就是使main线程处于等待状态,完了后再输出大小
latch.await();
//这里是main线程sleep一段时间(1秒),效果同latch.await();
/* try{
System.out.println(Thread.currentThread().getName());//当前线程输出的是main
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}*/
//System.out.println(concurrentHashMap.size());
System.out.println(hashMap.size());
}
}
因为多线程下HashMap是不安全的,所以结果:

而ConcurrentHashMap是线程安全的,结果如下图:

ConcurrentHashMap下,如果把CountDownLatch latch = new CountDownLatch(2000);中参数2000改成小于2000的值(1000)那么输出的结果如下:

因为countDown()计数器递减为0的时候,await()方法就不会再阻塞main线程,所以输出语句的执行可能会在所有线程put完成之前,因此结果不是2000
CountDownLatch在多线程程序中的应用的更多相关文章
- zz剖析为什么在多核多线程程序中要慎用volatile关键字?
[摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...
- 多线程程序中fork导致的一些问题
最近项目中,在使用多线程和多进程时,遇到了些问题. 问题描述:在多线程程序中fork出一个新进程,发现新的进程无法正常工作. 解决办法:将开线程的代码放在fork以后.也就是放在新的子进程中进行创建. ...
- Linux -- 在多线程程序中避免False Sharing
1.什么是false sharing 在对称多处理器(SMP)系统中,每个处理器均有属于自己的本地高速缓存区. 如图,CPU0和CPU1有各自的本地高速缓存区(cache).线程0和线程1会用到不同的 ...
- gdb常用命令及使用gdb调试多进程多线程程序
一.常用普通调试命令 1.简单介绍GDB 介绍: gdb是Linux环境下的代码调试⼯具.使⽤:需要在源代码⽣成的时候加上 -g 选项.开始使⽤: gdb binFile退出: ctrl + d 或 ...
- 《Java大学教程》—第22章 多线程程序
22.2 进程(process):P551时间切片(time-slicing):处理器只是完成了一个任务的一部分工作,然后完成下一个任务的一部分工作,因为处理吕每次完成工作的时间都非常短,因此看起来这 ...
- Linux下多线程编程中信号量介绍及简单使用
在Linux中有两种方法用于处理线程同步:信号量和互斥量. 线程的信号量是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作.如果一个程序中有多个线程试图改变一个信号量的值,系统将保 ...
- C# 多线程程序隐患
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 在 java 程序中怎么保证多线程的运行安全?(未完成)
在 java 程序中怎么保证多线程的运行安全?(未完成)
- java程序中的多线程(转)
为什么会排队等待? 下面的这个简单的 Java 程序完成四项不相关的任务.这样的程序有单个控制线程,控制在这四个任务之间线性地移动.此外,因为所需的资源 ― 打印机.磁盘.数据库和显示屏 -- 由于硬 ...
随机推荐
- OnSen UI结合AngularJs打造”美团"APP"我的”页面 --Hybrid App
1.页面效果图: 演示地址:http://www.nxl123.cn/bokeyuan/meiTuanDemo_mine/ 2.核心代码 mine.html: <ons-page id=&quo ...
- 基于C# winform实现图片流存储到文件
本文所述实例实现将一张图片上传到指定的文件夹,然后在窗体上的PictrueBox控件中显示出来. 具体功能代码如下: private void btnUpload_Click(object sende ...
- Confluence 6 编辑一个空间的配色方案
空间默认继承全局的配色方案.但是,如果你是空间管理员的话,你可以对默认继承的全局方案进行调整,使用自定义的配色方案. 为一个空间修改配色方案: 进入空间后,然后从边栏的底部选择 空间工具(Space ...
- CF438D 线段树 区间求和,区间求膜,单点更新
题目链接 题目大意: 给定一个长度为n的序列,要求能够执行m次下列操作: 1.查询区间[l,r]的和 2.将区间[l,r]的每一个数%=mod 3.修改第x个数为y 操作1,3都是线段树的基本操作,线 ...
- 第三周学习进度条+PSP0过程文档
第三周学习进度条 第三周 所花时间(包括上课) 14:30-15:35(65)+19:00-21:20(140)+17:52-19:00(68)+19:10-20:45(95)+21:00-22 ...
- IQC来料检验报表
***************************************************************** * System : XXXXXXXXX * Module : QM ...
- SEND EMAIL SO_DOCUMENT_SEND_API1
FUNCTION zcrm_send_email_and_attach . *"------------------------------------------------------- ...
- Oracle Cursor用法总结
cursor分为三种,一是直接声明为cursor变量,二是首先声明类型再声明变量,三是声明为sys_refcursor. (1)直接声明 declare cursor emp_cur is sele ...
- nginx开启fileinfo扩展
//实现网址 https://blog.csdn.net/m_nanle_xiaobudiu/article/details/80838424 (1) (2).make && make ...
- jackson实体转json时 为NULL不参加序列化的汇总
首先加入依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson ...