• 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

     

  • 相关阅读:
    JAVA Number类
    ConcurrentHashMap.Segment源码解析
    Java Concurrent包初探
    JAVA枚举类
    构造不可变类及其优点
    Unsafe类初探
    Paxos made simple 翻译尝试
    平行二叉堆和优先队列
    Android OpenCV学习
    Android-Java和HTML5交互-混合开发-优化
  • 原文地址:https://www.cnblogs.com/zhima-hu/p/7500341.html
Copyright © 2020-2023  润新知