CountDownLatch在多线程程序中的应用

Posted 芝麻_糊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

 

 

 

以上是关于CountDownLatch在多线程程序中的应用的主要内容,如果未能解决你的问题,请参考以下文章

ZeroMQ 在多线程应用程序中处理中断

在多线程应用程序中使用屏障的真实示例是啥?

利刃 MVVMLight 8:DispatchHelper在多线程和调度中的使用

java 多线程 27 :多线程组件之CountDownLatch

25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

在多线程应用程序中使用带有媒体基础接口的 P/Invoke 发生 AccessViolationException