CountDownLatch在多线程程序中的应用

一.CountDownLatch介绍

CountDownLatch是JDK1.5之后引入的,存在于java.util.concurrent包下,能够使一个线程等待其他线程完成动作后再执行。构造方法:
1  public CountDownLatch(int count) {
2         if (count < 0) throw new IllegalArgumentException("count < 0");
3         this.sync = new Sync(count);
4     }

主要方法:

countDown()方法每调用一次,计数器减1

await()方法使当前线程处于阻塞状态,知道计数器值为0

二.CountDownLatch使用

 1 package com;
 2
 3 import java.util.*;
 4 import java.util.concurrent.ConcurrentHashMap;
 5 import java.util.concurrent.ConcurrentMap;
 6 import java.util.concurrent.CountDownLatch;
 7 import java.util.concurrent.atomic.AtomicInteger;
 8
 9 /**
10  * CountDownLatch测试
11  */
12 class myThread<T> extends Thread {
13     CountDownLatch countDownLatch;
14     Map map;
15     //构造函数,传入的是Map
16     public myThread(CountDownLatch countDownLatch, Map map) {
17         this.countDownLatch = countDownLatch;
18         this.map = map;
19     }
20     public void run() {
21         map.put(Thread.currentThread().getName(),new Object());
22         countDownLatch.countDown();//线程执行一次就countDown计数器减少1
23     }
24 }
25
26 public class TestThreadAndCollection {
27     public static void main(String[] args) throws InterruptedException {
28         //表示测试100次
29         for (int i = 0; i < 100; i++) {
30             test();
31         }
32     }
33
34     public static  void test() throws InterruptedException {
35         CountDownLatch latch = new CountDownLatch(2000);
36         //使用HashMap,这是线程不安全的
37         Map<String ,Object> hashMap = new HashMap();
38         //使用ConcurrentHashMap,线程安全的
39         //Map<String ,Object> concurrentHashMap = new ConcurrentHashMap();
40         //两个for循环,2000个线程
41         for (int i = 0; i < 1000; i++) {
42             //多线程HashMap测试
43             //myThread mThread = new myThread(latch, hashMap);
44             //多线程concurrentHashMap测试
45             myThread mThread = new myThread(latch, hashMap);
46             mThread.start();
47         }
48         for (int i = 0; i < 1000; i++) {
49             myThread mThread = new myThread(latch, hashMap);
50             mThread.start();
51         }
52         //等待当前所有子线程执行完,这里也就是使main线程处于等待状态,完了后再输出大小
53         latch.await();
54         //这里是main线程sleep一段时间(1秒),效果同latch.await();
55        /* try{
56             System.out.println(Thread.currentThread().getName());//当前线程输出的是main
57             Thread.sleep(1000);
58         }catch(InterruptedException e){
59             e.printStackTrace();
60         }*/
61         //System.out.println(concurrentHashMap.size());
62         System.out.println(hashMap.size());
63     }
64 }

因为多线程下HashMap是不安全的,所以结果:

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

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

因为countDown()计数器递减为0的时候,await()方法就不会再阻塞main线程,所以输出语句的执行可能会在所有线程put完成之前,因此结果不是2000

时间: 2024-10-05 04:49:42

CountDownLatch在多线程程序中的应用的相关文章

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

最近项目中,在使用多线程和多进程时,遇到了些问题. 问题描述:在多线程程序中fork出一个新进程,发现新的进程无法正常工作. 解决办法:将开线程的代码放在fork以后.也就是放在新的子进程中进行创建. 产生原因:在使用fork时会将原来进程中的所有内存数据复制一份保存在子进程中.但是在拷贝的时候,但是线程是无法被拷贝的.如果在原来线程中加了锁,在使用的时候会造成死锁.以下是具体的例子(转发): 在多线程程序里,在”自身以外的线程存在的状态”下一使用fork的话,就可能引起各种各样的问题.比较典型

多线程程序中操作的原子性

[转]http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/ 多线程程序中操作的原子性 0. 背景 原子操作就 是不可再分的操作.在多线程程序中原子操作是一个非常重要的概念,它常常用来实现一些同步机制,同时也是一些常见的多线程Bug的源头.本文主要讨论了三 个问题:1. 多线程程序中对变量的读写操作是否是原子的?2. 多线程程序中对Bit field(位域)的读写操作是否是线程安全

C#OOP之十二 创建多线程程序

线程简介 在讲线程之前,我们先来看几个概念,程序.进程. 程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合. 进程:进程通俗的讲,就是正在执行的程序.一个进程通常就是一个正在执行的应用程序.Windows提供了"任务管理器",如下图所示: 1教室.exe为海天屏幕广播程序的进程:飞球.exe为飞球的进程:sqlserver.exe为Sql Server2005的进程:当我们启动了一个应用程序(或者说一个任务)时通常也就启动了一个进程.从上图可以看出每一个进程占一

java程序中的多线程(转)

为什么会排队等待? 下面的这个简单的 Java 程序完成四项不相关的任务.这样的程序有单个控制线程,控制在这四个任务之间线性地移动.此外,因为所需的资源 ― 打印机.磁盘.数据库和显示屏 -- 由于硬件和软件的限制都有内在的潜伏时间,所以每项任务都包含明显的等待时间.因此,程序在访问数据库之前必须等待打印机完成打印文件的任务,等等.如果您正在等待程序的完成,则这是对计算资源和您的时间的一种拙劣使用.改进此程序的一种方法是使它成为多线程的. 四项不相关的任务 class myclass { sta

浅谈多线程在java程序中的应用

在一个高并发的网站中,多线程是必不可少的.下面先说一下多线程在程序中的作用.1.提高前端请求的响应速度.当我们执行一个比较耗时的方法时,http请求得不到响应甚至会超时,这时如果业务上允许数据的延迟,我们可以使用多线程来进行处理比较耗时的方法.这样前端发送了请求,后端令开启了一个线程去处理任务,就不会阻塞主线程了.2.减清服务器的压力.包括我们的web容器,如tomcat.jetty等,还有数据库服务器等.因为我们使用了多线程,并且线程池大小有限制,如30,那么同时请求数据库的链接就限制为30了

在Web应用程序中执行计划任务(多线程)

在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务.实现计划任务的方法也有很多,可以采用SQLAgent执行存储过程来实现,也可以采用Windows任务调度程序来实现,也可以使用Windows服务来完成我们的计划任务,这些方法都是很好的解决方案.但是,对于Web应用程序来说,这些方法实现起来并不是很简单的,主机服务提供商或者不能直接提供这样的服务,或者需要你支付许多额外的费用. 本文就介绍

[转]极不和谐的 fork 多线程程序

极不和谐的 fork 多线程程序 继续前几天的话题.做梦幻西游服务器优化的事情.以往的代码,定期存盘的工作分两个步骤,把 VM 里的动态数据序列化,然后把序列化后的数据写盘.这两个步骤,序列化工作并没有独立在单独线程/进程里做,而是放在主线程的.IO 部分则在一个独立进程中. 序列化任务是个繁琐的过程.非常耗时(相对于 MMORPG 这个需要对用户请求快速反应的环境).当玩家同时在线人数升高时,一个简便的优化方法是把整个序列化任务分步完成,分摊到多个心跳内.这里虽然有一些数据一致性问题,但也有不

JAVA多线程编中的轮询锁与定时锁

显示锁                                                                                     Lock接口是Java 5.0新增的接口,该接口的定义如下: 1 2 3 4 5 6 7 8 publicinterface Lock {     void lock();     void lockInterruptibly() throws InterruptedException;     boolean tryLo

为什么linux下多线程程序如此消耗虚拟内存【转】

转自:http://blog.csdn.net/chen19870707/article/details/43202679 权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 探索 灵光一现 刨根问底 意外发现 Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:Jan.27th, 2015 最近游戏已上线运营,进行服务器内存优化,发现一个非常奇妙的问题,我们的认证服