zoukankan      html  css  js  c++  java
  • Concurrent同步工具类01

    CountDownLatch介绍

    java.util.concurrent.CountDownLatch,我们可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。

    可以为CountDownLatch对象设置一个初始的数字作为计数值,任何调用这个对象上的await()方法都会阻塞,直到这个计数器的计数值被其他的线程减为0为止。

    应用场景

    CountDownLatch的一个非常典型的应用场景是:有一个任务A想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如想要继续往下执行的任务A调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务A将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。CountDownLatch 以一个给定的数量初始化。countDown() 每被调用一次,这 一数量就减一。

    举例:

    假设有老板和3个工人的雇佣关系,只有等3个工人的工作完成以后,老板才会结束工作完成情况的检查。

     1 package com.test.lesson01;
     2 
     3 import java.util.concurrent.CountDownLatch;
     4 import java.util.concurrent.ExecutorService;
     5 import java.util.concurrent.Executors;
     6 
     7 public class Demo3 {
     8     public static void main(String[] args) {
     9         ExecutorService executorService= Executors.newFixedThreadPool(4);
    10         CountDownLatch countDownLatch=new CountDownLatch(3);
    11         Worker worker1=new Worker(countDownLatch,"w1");
    12         Worker worker2=new Worker(countDownLatch,"w2");
    13         Worker worker3=new Worker(countDownLatch,"w3");
    14         Boss boss=new Boss(countDownLatch);
    15         executorService.execute(worker1);
    16         executorService.execute(worker2);
    17         executorService.execute(worker3);
    18         executorService.execute(boss);
    19         executorService.shutdown();
    20     }
    21 }
    22 
    23 
    24 
    25 class Worker implements Runnable{
    26     private CountDownLatch countDownLatch;
    27     private String name;
    28     public Worker(CountDownLatch countDownLatch,String name){
    29         this.countDownLatch=countDownLatch;
    30         this.name=name;
    31     }
    32 
    33     @Override
    34     public void run() {
    35         try{
    36             Thread.sleep(1000);
    37             System.out.println("------开始干活啦-------");
    38             Thread.sleep(500);
    39         }catch(InterruptedException e){
    40             e.printStackTrace();
    41         }
    42         System.out.println("-----工人"+name+"干活结束----");
    43         countDownLatch.countDown();
    44     }
    45 }
    46 
    47 
    48 class Boss implements Runnable{
    49     private CountDownLatch countDownLatch;
    50     public Boss(CountDownLatch countDownLatch){
    51         this.countDownLatch=countDownLatch;
    52     }
    53 
    54     @Override
    55     public void run() {
    56         System.out.println("老板正在等待所有的工人完工");
    57         try {
    58             countDownLatch.await();//等待所有和countDown有关的线程执行完毕后才执行本线程
    59         } catch (InterruptedException e) {
    60             e.printStackTrace();
    61         }
    62         System.out.println("老板检查工人完工情况结束");
    63     }
    64 }
    View Code

    运行结果之一为:(工人工作的先后顺序可能每次运行不一致,但是“老板检查工人完工情况结束”一定是最后完成)

    1 老板正在等待所有的工人完工
    2 ------开始干活啦-------
    3 ------开始干活啦-------
    4 ------开始干活啦-------
    5 -----工人w1干活结束----
    6 -----工人w3干活结束----
    7 -----工人w2干活结束----
    8 老板检查工人完工情况结束
    View Code

     如果上述countDownLatch的初始化数量由3改为5,将会线程阻塞,其中一种运行情况为:

  • 相关阅读:
    javascript判断浏览器类型与版本
    javascript动态创建VML
    getElementsByAttribute
    javascript替换字符
    javascript contains方法
    sql2005性能优化(在32位系统上突破2G内存使用量的方法)
    详解如何让WIN2003和SQL2005支持4G以上内存
    搭建Windows CE 6.0团队开发环境
    MS SQL Server启用对4G以上物理内存的支持
    USB 3G Wireless Modem(2010.10.28更新)
  • 原文地址:https://www.cnblogs.com/Hermioner/p/14191698.html
Copyright © 2011-2022 走看看