java多线程-CyclicBarrier

  • 介绍

  一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

  CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

  • 主要方法
  • 1 //设置parties、count及barrierCommand属性。
    2 CyclicBarrier(int):
    3 //当await的数量到达了设定的数量后,首先执行该Runnable对象。
    4 CyclicBarrier(int,Runnable):
    5 //通知barrier已完成线程
    6 await():  
  • 应用场景

  1:CyclicBarrier 表示大家彼此等待,大家集合好后才开始出发,分散活动后又在i指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始就餐。

  代码:

 1 public class CyclicBarrierTest {
 2     public static void main(String[] args){
 3         ExecutorService pool = Executors.newCachedThreadPool();
 4         final CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
 5
 6         for (int i = 0; i < 3; i++) {
 7             Runnable runnable = new Runnable() {
 8                 @Override
 9                 public void run(){
10                     try {
11                         Thread.sleep(new Random().nextInt(5000));
12                     } catch (InterruptedException e) {
13                         // TODO Auto-generated catch block
14                         e.printStackTrace();
15                     }
16                     System.out.println(Thread.currentThread().getName()+"到达地点一,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
17                     try {
18                         cyclicBarrier.await();//障碍等待点
19                     } catch (InterruptedException e) {
20                         // TODO Auto-generated catch block
21                         e.printStackTrace();
22                     } catch (BrokenBarrierException e) {
23                         // TODO Auto-generated catch block
24                         e.printStackTrace();
25                     }
26                     try {
27                         Thread.sleep(new Random().nextInt(5000));
28                     } catch (InterruptedException e) {
29                         // TODO Auto-generated catch block
30                         e.printStackTrace();
31                     }
32                     System.out.println(Thread.currentThread().getName()+"到达地点二,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"继续出发":"继续等待"));
33                     try {
34                         cyclicBarrier.await();//障碍等待点
35                     } catch (InterruptedException e) {
36                         // TODO Auto-generated catch block
37                         e.printStackTrace();
38                     } catch (BrokenBarrierException e) {
39                         // TODO Auto-generated catch block
40                         e.printStackTrace();
41                     }
42                     try {
43                         Thread.sleep(new Random().nextInt(5000));
44                     } catch (InterruptedException e) {
45                         // TODO Auto-generated catch block
46                         e.printStackTrace();
47                     }
48                     System.out.println(Thread.currentThread().getName()+"到达地点三,当前等待人数为"+(cyclicBarrier.getNumberWaiting()+1)+(cyclicBarrier.getNumberWaiting()+1==3?"人齐了出发":"继续等待"));
49                     try {
50                         cyclicBarrier.await();//障碍等待点
51                     } catch (InterruptedException e) {
52                         // TODO Auto-generated catch block
53                         e.printStackTrace();
54                     } catch (BrokenBarrierException e) {
55                         // TODO Auto-generated catch block
56                         e.printStackTrace();
57                     }
58                 }
59             };
60             pool.execute(runnable);
61         }
62         pool.shutdown();
63     }
64 }

  执行结果:

1 pool-1-thread-3到达地点一,当前等待人数为1继续等待
2 pool-1-thread-1到达地点一,当前等待人数为2继续等待
3 pool-1-thread-2到达地点一,当前等待人数为3继续出发
4 pool-1-thread-1到达地点二,当前等待人数为1继续等待
5 pool-1-thread-3到达地点二,当前等待人数为2继续等待
6 pool-1-thread-2到达地点二,当前等待人数为3继续出发
7 pool-1-thread-3到达地点三,当前等待人数为1继续等待
8 pool-1-thread-2到达地点三,当前等待人数为2继续等待
9 pool-1-thread-1到达地点三,当前等待人数为3人齐了出发

  2:在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。

  代码:

 1 public class CyclicBarrierTest1 {
 2     public static void main(String[] args) {
 3         ExecutorService threadPool = Executors.newCachedThreadPool();
 4         CyclicBarrier barrier = new CyclicBarrier(5, new mainTask());
 5         for (int i = 0; i < 5; i++) {
 6             subTask subTask = new subTask(barrier);
 7             threadPool.execute(subTask);
 8         }
 9         threadPool.shutdown();
10     }
11 }
12
13 class subTask implements Runnable{
14     private CyclicBarrier barrier;
15
16     public subTask(CyclicBarrier barrier) {
17         super();
18         this.barrier = barrier;
19     }
20     @Override
21     public void run() {
22         System.out.println(Thread.currentThread().getName()+"正在执行");
23         try {
24             Thread.sleep(5000);
25         } catch (InterruptedException e) {
26             // TODO Auto-generated catch block
27             e.printStackTrace();
28         }
29         System.out.println(Thread.currentThread().getName()+"执行完毕,等待其他结果");
30         try {
31             barrier.await();
32         } catch (InterruptedException e) {
33             // TODO Auto-generated catch block
34             e.printStackTrace();
35         } catch (BrokenBarrierException e) {
36             // TODO Auto-generated catch block
37             e.printStackTrace();
38         }
39
40     }
41 }
42 class mainTask implements Runnable{
43
44     @Override
45     public void run() {
46         System.out.println("总任务执行完毕");
47     }
48
49 }

  执行结果:

 1 pool-1-thread-2正在执行
 2 pool-1-thread-3正在执行
 3 pool-1-thread-1正在执行
 4 pool-1-thread-4正在执行
 5 pool-1-thread-5正在执行
 6 pool-1-thread-2执行完毕,等待其他结果
 7 pool-1-thread-5执行完毕,等待其他结果
 8 pool-1-thread-1执行完毕,等待其他结果
 9 pool-1-thread-4执行完毕,等待其他结果
10 pool-1-thread-3执行完毕,等待其他结果
11 总任务执行完毕

  另外,CyclicBarrier是可以重用的,它可以在使用完后继续使用,这就是Cyclic(循环)的意思。

时间: 2024-08-11 00:24:05

java多线程-CyclicBarrier的相关文章

Java多线程与并发库高级应用之公共屏障点CyclicBarrier

一个小队去登山,每位队员登山的速度不同.山上有几个集合点,在每一集合点处,先到达的队员只有等后面的队员全部到达集合点后才能继续向下一个集合点出发. JDK1.5提供的CyclicBarrier模拟了这种情况.每一个线程相当于一个登山队员,CyclicBarrier相当于山上的集合点.只有等所有线程都执行到了CyclicBarrier后才可以继续向下执行. CyclicBarrier允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程

JAVA多线程提高十:同步工具CyclicBarrier与CountDownLatch

今天继续学习其它的同步工具:CyclicBarrier与CountDownLatch 一.CyclicBarrier CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用.因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier. CyclicBarrier类似于CountDownL

Java多线程面试15道

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者有足够的Java线程与并发方面的知识,因为候选人中有很多只浮于表面.用于直接面向市场交易的高容量和低延时的电子交易系统在本质上是并发的.下面这些是我在不同时间不同地点喜欢问的Jav

40个Java多线程问题总结

前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不

【转】 Java 多线程之一

转自   Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源. 2.Java标准库提供了进程和线程相关

[转载] java多线程学习-java.util.concurrent详解(一) Latch/Barrier

转载自http://janeky.iteye.com/blog/769965 Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent, 提供了大量高级工具,可以帮助开发者编写高效.易维护.结构清晰的Java多线程程序.从这篇blog起,我将跟大家一起共同学习这些新的Java多线程构件 1. CountDownLatch     我们先来学习一下JDK1.5 API中关于这个类的详细介绍: “一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个

java多线程学习(3)

1)竞争条件 在实际的多线程应用中,通常会有两个或多个线程需要对共同的对象进行共享访问,如果两个线程访问相同的对象,而且每一个都调用了一个会改变对象状态的方法, 那么,线程就会相互倾轧.根据各个线程访问数据的不同顺序,可能会产生腐蚀现象.这种情况通常称为竞争条件. 2)同步 为了多个线程对共享数据的腐蚀,就需要对数据的存取实现同步:常用的同步方法有3种: 1.Reenlock 用Reenlock保护代码块的基本机构如下: 1 Lock myLock=new ReenLock; 2 3 myLoc

java多线程并发概览

一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运行的exe就是一个进程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. "同时"执行是人的感觉,在线程之间实际上轮换执行. 二.Java中的线程 在J

Java多线程问题总结

前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题. 这些多线程的问题,有些来源于各大网站.有些来源于自己的思考.可能有些问题网上有.可能有些问题对应的答案也有.也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不