一.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在多线程程序中的应用的更多相关文章

  1. zz剖析为什么在多核多线程程序中要慎用volatile关键字?

    [摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...

  2. 多线程程序中fork导致的一些问题

    最近项目中,在使用多线程和多进程时,遇到了些问题. 问题描述:在多线程程序中fork出一个新进程,发现新的进程无法正常工作. 解决办法:将开线程的代码放在fork以后.也就是放在新的子进程中进行创建. ...

  3. Linux -- 在多线程程序中避免False Sharing

    1.什么是false sharing 在对称多处理器(SMP)系统中,每个处理器均有属于自己的本地高速缓存区. 如图,CPU0和CPU1有各自的本地高速缓存区(cache).线程0和线程1会用到不同的 ...

  4. gdb常用命令及使用gdb调试多进程多线程程序

    一.常用普通调试命令 1.简单介绍GDB 介绍: gdb是Linux环境下的代码调试⼯具.使⽤:需要在源代码⽣成的时候加上 -g 选项.开始使⽤: gdb binFile退出: ctrl + d 或 ...

  5. 《Java大学教程》—第22章 多线程程序

    22.2 进程(process):P551时间切片(time-slicing):处理器只是完成了一个任务的一部分工作,然后完成下一个任务的一部分工作,因为处理吕每次完成工作的时间都非常短,因此看起来这 ...

  6. Linux下多线程编程中信号量介绍及简单使用

    在Linux中有两种方法用于处理线程同步:信号量和互斥量. 线程的信号量是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作.如果一个程序中有多个线程试图改变一个信号量的值,系统将保 ...

  7. C# 多线程程序隐患

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 在 java 程序中怎么保证多线程的运行安全?(未完成)

    在 java 程序中怎么保证多线程的运行安全?(未完成)

  9. java程序中的多线程(转)

    为什么会排队等待? 下面的这个简单的 Java 程序完成四项不相关的任务.这样的程序有单个控制线程,控制在这四个任务之间线性地移动.此外,因为所需的资源 ― 打印机.磁盘.数据库和显示屏 -- 由于硬 ...

随机推荐

  1. OnSen UI结合AngularJs打造”美团"APP"我的”页面 --Hybrid App

    1.页面效果图: 演示地址:http://www.nxl123.cn/bokeyuan/meiTuanDemo_mine/ 2.核心代码 mine.html: <ons-page id=&quo ...

  2. 基于C# winform实现图片流存储到文件

    本文所述实例实现将一张图片上传到指定的文件夹,然后在窗体上的PictrueBox控件中显示出来. 具体功能代码如下: private void btnUpload_Click(object sende ...

  3. Confluence 6 编辑一个空间的配色方案

    空间默认继承全局的配色方案.但是,如果你是空间管理员的话,你可以对默认继承的全局方案进行调整,使用自定义的配色方案. 为一个空间修改配色方案: 进入空间后,然后从边栏的底部选择 空间工具(Space ...

  4. CF438D 线段树 区间求和,区间求膜,单点更新

    题目链接 题目大意: 给定一个长度为n的序列,要求能够执行m次下列操作: 1.查询区间[l,r]的和 2.将区间[l,r]的每一个数%=mod 3.修改第x个数为y 操作1,3都是线段树的基本操作,线 ...

  5. 第三周学习进度条+PSP0过程文档

    第三周学习进度条    第三周 所花时间(包括上课) 14:30-15:35(65)+19:00-21:20(140)+17:52-19:00(68)+19:10-20:45(95)+21:00-22 ...

  6. IQC来料检验报表

    ***************************************************************** * System : XXXXXXXXX * Module : QM ...

  7. SEND EMAIL SO_DOCUMENT_SEND_API1

    FUNCTION zcrm_send_email_and_attach . *"------------------------------------------------------- ...

  8. Oracle Cursor用法总结

    cursor分为三种,一是直接声明为cursor变量,二是首先声明类型再声明变量,三是声明为sys_refcursor. (1)直接声明 declare cursor emp_cur  is sele ...

  9. nginx开启fileinfo扩展

    //实现网址 https://blog.csdn.net/m_nanle_xiaobudiu/article/details/80838424 (1) (2).make && make ...

  10. jackson实体转json时 为NULL不参加序列化的汇总

    首先加入依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson ...