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 程序完成四项不相关的任务.这样的程序有单个控制线程,控制在这四个任务之间线性地移动.此外,因为所需的资源 ― 打印机.磁盘.数据库和显示屏 -- 由于硬 ...
随机推荐
- 使用getCurrentPosition方法实时获取当前Geolocation信息(附源码文件)--html5、JavaScript
使用getCurrentPosition方法实时获取当前Geolocation信息: 1.getCurrentPosition方法的使用 navigator.geolocation.getCurren ...
- C#如何实现类似QQ那样靠边隐藏的功能
http://www.cnblogs.com/yechensi/archive/2009/08/02/1537145.html C#如何实现类似QQ那样靠边隐藏的功能 你想过为自己的程序添加靠边隐藏的 ...
- hihocoder-1415 后缀数组三·重复旋律3 两个字符串的最长公共子串
把s1,s2拼接,求Height.相邻的Height判断左右串起点是否在两个串中,另外对Height和s1.length()-SA[i-1]取min. #include <iostream> ...
- 小程序获取openid 小程序授权
小程序获取openid 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. wx.login(Object object) 调用接口获取登录凭证(cod ...
- chrome 自动加载flash
class Login(unittest.TestCase): #初始 def setUp(self): chromeOpitons = Options() prefs = { # "pro ...
- 『TensorFlow』SSD源码学习_其五:TFR数据读取&数据预处理
Fork版本项目地址:SSD 一.TFR数据读取 创建slim.dataset.Dataset对象 在train_ssd_network.py获取数据操作如下,首先需要slim.dataset.Dat ...
- 第二阶段——个人工作总结DAY10
1.昨天做了什么:昨天其实什么也没实现. 2.今天打算做什么:今天就软件,等到审核过了,再看看软件最后后台是怎么实现的. 3.遇到的困难:后台自己都没有实现.
- leetcode-algorithms-26 Remove Duplicates from Sorted Array
leetcode-algorithms-26 Remove Duplicates from Sorted Array Given a sorted array nums, remove the dup ...
- ORACLE SQL 函数 INITCAP()
INITCAP() 假设c1为一字符串.函数INITCAP()是将每个单词的第一个字母大写,其它字母变为小写返回. 单词由空格,控制字符,标点符号等非字母符号限制. select initcap('h ...
- MongoDB 教程(三):MongoDB 的下载、安装和配置
一.下载 下载地址:https://www.mongodb.com/download-center#community(这里是Windows 版,其他版本也可以在该网页进行下载) 版本选择: Mong ...