1. 程式人生 > >CountDownLatch在多線程程序中的應用

CountDownLatch在多線程程序中的應用

exception pac 所有 args lar hash oid sys exc

一.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在多線程程序中的應用