Java编程思想中的例子
import javax.validation.constraints.Size;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; class TaskPortion implements Runnable{ private static int count;
private final int id=count++;
private final CountDownLatch latch;
private static Random random=new Random(47); public TaskPortion(CountDownLatch latch) {
this.latch = latch;
} public void run() {
try {
doWork();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown(); } public void doWork() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(random.nextInt(1000));
System.out.println(this+"complete"); }
@Override
public String toString() {
return "TaskPortion: "+String.format("%1$-2d",id);
}
}
class WaitingTask implements Runnable{ private final CountDownLatch latch;
private static int count;
private final int id=count++; public WaitingTask(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
System.out.println(this);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "waiting task pass"+String.format("%1$-2d",id);
}
}
public class CountDownLatchDemo { private static final int SIZE=20;
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
CountDownLatch latch=new CountDownLatch(SIZE);
for (int i=0;i<SIZE;i++)
executorService.execute(new TaskPortion(latch)); //
for (int i = 0; i < SIZE; i++) {
executorService.execute(new WaitingTask(latch));
     executorService.shutdown();
    } 
  }
}

countdownlatch中有个计数器,当计数器减少到0的时候,释放所有等待的线程,coutDown()会让计数器的值减少,调用await()的线程将会进入等待状态,直到调用countdownlatch使得计数器数值减少到0,所有等待的线程都会开始执行。

CyclicBarrier

这个相对于上面的countdownlatch来说,这种可以重复的使用,而且await()已经具备countdownlatch中的countdown()和await()两种方法的作用。(前者await()被线程调用一次计数减一,后者不会,只能通过countdown())

首先了解他的构造方法。

方法

自己独立敲了一段书上的模拟赛马的demo(来自于Java编程思想)

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*; class Horse implements Runnable{
private CyclicBarrier barrier; //ByclicBarrier用来控制本类的在释放屏障之前的动作,由构造函数传入
private int stride=0;               //马跑得轨迹
private static int count;             //马的数量
private final int id=count++;          //设置马的id
private Random random = new Random(47);    //模拟赛马 public Horse(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try{
while(!Thread.interrupted()){            //这里模拟赛马的过程
TimeUnit.MILLISECONDS.sleep(500);
barrier.await();
stride+=random.nextInt(3);
}
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public String toString() {
return "Horse "+id+" ";
}
public String getTrack(){
StringBuilder s=new StringBuilder();//返回马当前到达屏障之后走的路径
for (int i = 0; i < stride; i++) {
s.append("=");
}
return s.toString();
}
public int getStride() {
return stride; //马走了多少
} public int getId() {
return id;
}
}
class HorseRace {
private int nhorse;
private ExecutorService exec;
private final int FINISH_LINE = 75;
private CyclicBarrier barrier;
List<Horse> horses = new ArrayList<Horse>();
private String track;
public HorseRace(int nhorse, ExecutorService executorService) {
exec = executorService;
this.nhorse = nhorse;
StringBuilder s = new StringBuilder();
for (int i = 0; i < FINISH_LINE; i++) {
s.append("=");
}
track = s.toString();
System.out.println(s.toString());
barrier = new CyclicBarrier(nhorse, () -> { //表达式中定义了释放屏障之前的动作,打印当前所有马的路程并且判断是否有的码已经到达终点
System.out.println(track);
for (Horse horse : horses) {
System.out.println(horse.getTrack());
if (horse.getStride() > FINISH_LINE) {
System.out.println(horse.getId() + " won");
exec.shutdownNow();
return;
}
}
});
for (int i = 0; i < nhorse; i++) {
Horse horse = new Horse(barrier);
exec.execute(horse);
horses.add(horse);
}
}
}
public class HorseRaceDeno {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
new HorseRace(7, executorService);
}
}

两者区别总结:

CyclicBarrier:是可以重重复使用的,只有等待线程积累到一定的数量的时候才会释放屏障,在释放屏障的时候还可以使用接口初始化CyclicBarrier变量(在里面定义释放屏障之前的动作,可以是释放线程池,终止上面所说的线程)。也可以使用只有int数据类型创建CyclicBarrier变量,这样只有在释放屏障的时候没有多余的动作。

CountDownLatch:含有两个重要的方法CountDown()和await(),前者调用一次,CountDownLatch对象就会计数减少一次。await()导致当前线程等待计数器减少到零为止,除非出现中断的情况,而且CountDownLatch只有一次的机会,只会阻塞线程一次。

触发屏障的事件不同:前者只有足够的线程调用await时候才会触发线程,后者是计数器减少到零的时候才会触发屏障,但是导致计数器减少的可能只是一个线程。

Java中CountDownLatch和CyclicBarrier的更多相关文章

  1. Java中CountDownLatch和CyclicBarrier的使用和比较

    CountDownLatch和CyclicBarrier同为Java1.5开始引入的,应用于多线程编程中的一种工具,二者用途十分相近,十分容易混淆. CountDownLatch CountDownL ...

  2. java并发编程中CountDownLatch和CyclicBarrier的使用

    在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景,遇到这样的场景应该如何解决? 如果是一个线程等待一个线程,则可以通过await()和notify()来实现: 如果是一个线程等待多个线程 ...

  3. 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...

  4. java并发--CountDownLatch、CyclicBarrier和Semaphore

    在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下 ...

  5. Java多线程-CountDownLatch、CyclicBarrier、Semaphore

    上次简单了解了多线程中锁的类型,今天要简单了解下多线程并发控制的一些工具类了. 1. 概念说明: CountDownLatch:相当于一个待执行线程计数器,当计数减为零时表示所有待执行线程都已执行完毕 ...

  6. Java的CountDownLatch和CyclicBarrier的理解和区别

    CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘.本文将通过通俗的例子并结合代码讲解两者的使用方法和区别. CountDownLatch和Cycl ...

  7. Java中CountDownLatch类的使用

    0.CountDownLatch作用 1) Java api中的解释:一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 2) CountDownLatch可以使J ...

  8. java面试-CountDownLatch、CyclicBarrier、Semaphore谈谈你的理解

    一.CountDownLatch 主要用来解决一个线程等待多个线程的场景,计数器不能循环利用 public class CountDownLatchDemo { public static void ...

  9. JAVA中CountDownLatch的简单示例

    public static void main(String[] args) throws InterruptedException { CountDownLatch latch =new Count ...

随机推荐

  1. poj 3264 倍增 ST表

    #include<iostream> #include<cmath> using namespace std; ; int a[maxn]; ]; ]; int quick(i ...

  2. python: 文件的读写

    #文件的读取.py a=open('test.txt').readline() #只读取文件第一行,保存为字符串格式 b=open('test.txt').read() #读取全部内容,保存为字符串格 ...

  3. Java类加载过程及static详解

    类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段. 其中类加载过程包括加载.验证.准备.解析和初始化五个阶段. 类加载器的任务就是根据一个类的 ...

  4. a small notepad++ plugin to support doxygen 1key generate

    Precondition: doxygen in c:\ folder testdoxygen.bat --- path %path%;C:\Doxygen;C:\Doxygen\graphviz\b ...

  5. 1.1.20 Word不能保存问题

    1.进入如下目录:C:\用户(user)\Administrator\AppData\Roaming\Microsoft\Templates 2.找到Normal和NormalOld的两个文件,删除. ...

  6. PCB行业研究

    PCB行业研究 PCB产业上下游 关于HDI电路板 主要用于手机行业,对电路板面积有严格要求. 啥时候铜材料上涨

  7. Docker Images for MySQL Group Replication 5.7.14

    In this post, I will point you to Docker images for MySQL Group Replication testing. There is a new ...

  8. WIN7 WIN10赋予文件或者文件夹完全访问权限

    WIN7 WIN10赋予文件或者文件夹完全访问权限win7文件夹图标中多了一把小锁打不开文件夹怎么办?解决办法一:右击目录→取得管理员权限!该方法适用于win7旗舰版.解决办法二:添加everyone ...

  9. 【剑指offer】反转链表

    输入一个链表,反转链表后,输出新链表的表头. *与之前的问题不同,这里需要修改链表的指向(之前的问题,不需要修改结点的指针,只需使用栈保存每个结点的值) *注意非空处理以及最后一个结点指针的修改 /* ...

  10. DokuWiki 插件使用

    本身DokuWiki提供了一些公共,但是不是很强大,所以可以安装一些插件. 安装方法可以参考:https://www.dokuwiki.org/extensions 下面列举出我觉得好用的一些插件: ...