java并发(一) CountDownLatch (在多个线程都结束后再去执行某个任务)

来源:互联网 发布:司法拍卖淘宝网房产 编辑:程序博客网 时间:2024/04/30 14:16

一、使用java.util.concurrent.CountDownLatch

  Java的util.concurrent包里面的CountDownLatch其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。
  你可以向CountDownLatch对象设置一个初始的数字作为计数值,任何调用这个对象上的await()方法都会阻塞,直到这个计数器的计数值被其他的线程减为0为止。
  CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。
  举个例子,有三个工人在为老板干活,这个老板有一个习惯,就是当三个工人把一天的活都干完了的时候,他就来检查所有工人所干的活。记住这个条件:三个工人先全部干完活,老板才检查。所以在这里用Java代码设计两个类,Worker代表工人,Boss代表老板,具体的代码实现如下:

Worker类(单独的线程):

复制代码
package cn.edu.bupt.thread.threadnotify;import java.util.Random;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;public class Worker implements Runnable{    private CountDownLatch downLatch;    private String name;    public Worker(CountDownLatch downLatch, String name)    {        this.downLatch = downLatch;        this.name = name;    }    @Override    public void run()    {        this.doWork();        try        {            TimeUnit.SECONDS.sleep(new Random().nextInt(10));        }        catch (InterruptedException ie)        {        }        System.out.println(this.name + "活干完了!");        this.downLatch.countDown();    }    private void doWork()    {        System.out.println(this.name + "正在干活...");    }}
复制代码

 

 

 Boss类(单独的线程):

复制代码
package cn.edu.bupt.thread.threadnotify;import java.util.concurrent.CountDownLatch;public class Boss implements Runnable{    private CountDownLatch downLatch;    public Boss(CountDownLatch downLatch)    {        this.downLatch = downLatch;    }    @Override    public void run()    {        System.out.println("老板正在等所有的工人干完活......");        try        {            this.downLatch.await();        }        catch (InterruptedException e)        {        }        System.out.println("工人活都干完了,老板开始检查了!");    }}
复制代码

 

 

Main:

复制代码
package cn.edu.bupt.thread.threadnotify;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class CountDownLatchDemo{    public static void main(String[] args)    {        ExecutorService executor = Executors.newCachedThreadPool();        CountDownLatch latch = new CountDownLatch(3);            Worker w1 = new Worker(latch, "张三");        Worker w2 = new Worker(latch, "李四");        Worker w3 = new Worker(latch, "王二");            Boss boss = new Boss(latch);                executor.execute(boss);        executor.execute(w3);        executor.execute(w2);        executor.execute(w1);                executor.shutdown();    }    }
复制代码

 

上例中的的ExecutorService接口和Executors类的作用类似于newThread(Runnable r).start()的作用,就是启动一个新的线程。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 有数组$array=array(“a”=>2,”b”=>6,”c”=>5) 有数组$array=array(“a”=>2,”b”=>6,”c”=>5) 有数组$array=array(“a”=>2,”b”=>6,”c”=>5)排序 php对一个数组按某个键值排序 有数组$array=array(“a”=>2,”b”=>6,”c”=>5);用php实现对以上数组进 $array=array(“a”=>2,”b”=>6,”c”=>5);用php实现对以上数组大小排序 $array=array(“a”=>2,”b”=>6,”c”=>5) $array=array(“a”=>2,”b”=>6,”c”=>5)排序 Linux去掉某个文件所有者同组用户的写权限 Linux.sed命令显示某个文件的第五行 Linux输出该文件的奇数行 Linuxsed命令在文件的最后一行插入该文件的的统计信息,包含多少行,多少个单词,多个字符 Linuxcut命令 Linux.cut命令 Linux.cut命令提出a文件中 Linux.cut命令提出a文件中 Linux.ls Linux创建文件 Linux修改文件的时间 Linux创建文件 Linux修改文件的时间 数字图像分析 数字图像分析中科大 希島 斗鱼 中国球轴承反倾销 中国球轴承反倾销案 MMaseagniandHChi.Optimalquasi-MonteCarlovaluationo [10]HoCTB,LiaoCK,KimHTValuingInternetCompanies:ADE javaweb注册界面 子串替换 C子串替换 dijstra mfc mfc鼠标 比较字符串 比较字符串 wiki搭建 kmp算法实现文本文件单词的检索与计数 centos鼠标消失 keypressed