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. 快速排序的两种实现 -- 种轴partition : 比值partition(更精巧)

    实现1:种轴partition,not in place--取定枢轴,将小于等于枢轴的放到枢轴左边,大于枢轴的放到右边 # python algorithm en_2nd edition p125de ...

  2. CRM项目之stark组件

    . stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...

  3. 20165308实验三 敏捷开发与XP实践实验报告

    实验三 敏捷开发与XP实践实验报告 实验目的 安装 alibaba 插件,解决代码中的规范问题.再研究一下Code菜单,找出一项让自己感觉最好用的功能. 在码云上把自己的学习搭档加入自己的项目中,确认 ...

  4. dos2unix 批量转化文件

    在windows和linux双平台下开发,同时也用git作为同步工具,但前期没有注意,导致很多文件使用windows下的换行符CRLF 参考资料了解dos2unix可以转化格式. 但有个问题,虽然可以 ...

  5. Python脚本模拟僵尸进程与孤儿进程

    最近一台机器的systemd内存高达30%多,一直不变,后来排查是僵尸进程,什么是僵尸进程呢,只能google,百度等先了解,然后自己总结了一下,虽然这是基础的东西,但是对于我来说就如新大陆一样.花了 ...

  6. redis 双写一致性 看一篇成高手系列1

    首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用.在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作. 但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存.又或者 ...

  7. 【java】final修饰符介绍

    final: 最终,作为一个修饰符特点:1.可以修饰类,函数,变量2.被final修的的类不能被继承.因此类用final修饰可以避免被继承,被子类重写功能.3.被final修饰的方法不可以被重写.4. ...

  8. 阿里四不像Fourinone

    阿里四不像——分布式核心技术框架 Fourinone https://blog.csdn.net/shero_zsmj/article/details/52277194

  9. Ubuntu 14.10 下Hive配置

    1 系统环境 Ubuntu 14.10 JDK-7 Hadoop 2.6.0 2 安装步骤 2.1 下载Hive 我第一次安装的时候,下载的是Hive-1.2.1,配置好之后,总是报错 [ERROR] ...

  10. HTML的day1 HTML的标签

    a标签和锚点 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...