`

CyclicBarrier

    博客分类:
  • JDK
阅读更多
CyclicBarrier

官方解释:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(common barrier point).在涉及一组固定大小的线程程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为barrier在释放等待线程后可以重用,所以称它为循环的barrier.
CyclicBarrier支持一个可选的Runnable命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作很有用.
CyclicBarrier和CountDownLatch不同,CyclicBarrier是当await数量到达了设定的数量后,才继续往下执行,在之前讲ThreadPoolExecutor的例子曾使用CyclicBarrier,例子中采用了CyclicBarrier来确保所有线程几乎同时开始运行.
CyclicBarrier(int):
设置parties,count及barrierCommand属性.
另一个构造器允许传入一个实现Runnable的对象,当await数量到达了设定的数量后,会首先执行此Runable对象.[到时候必须测试]
Await()
首先进行加锁操作,然后对count属性执行减1操作,如果减后的值等于0,则执行传入的Runnable对象。执行完毕后将ranAction设置为true,调用nextGeneration方法并返回0,nextGeneration方法主要调用trip condition的sigalAll;如果count减1后的值不等0,则调用trip Condition的await或await(设置时间)进入等待,直到trip Condition被唤醒,线程被interrupt或超时,从等待状态恢复后;它是基于ReentrantLock和Condition来实现,而CountDownLatch是使用Sync来实现同步.
官方讲解:
* <p>If the barrier action does not rely on the parties being suspended when
* it is executed, then any of the threads in the party could execute that
* action when it is released. To facilitate this, each invocation of
* {@link #await} returns the arrival index of that thread at the barrier.
* You can then choose which thread should execute the barrier action, for
* example:
* <pre>  if (barrier.await() == 0) {
*     // log the completion of this iteration
*   }</pre>
如果线程不需要等待,没有关联性,那么当所有线程执行完后,在这里可以添加完成的一些操作
对于失败的同步尝试,CyclicBarrier 使用了一种快速失败的、要么全部要么全不 (all-or-none) 的破坏模式:如果因为中断、失败或者超时等原因,导致线程过早地离开了屏障点,那么其他所有线程(甚至是那些尚未从以前的 await() 中恢复的线程)也将通过 BrokenBarrierException(如果它们几乎同时被中断,则用 InterruptedException)以反常的方式离开。

如果屏障操作在执行时不依赖于正挂起的线程,则线程组中的任何线程在获得释放时都能执行该操作。为方便此操作,每次调用 await() 都将返回能到达屏障处的线程的索引。然后,您可以选择哪个线程应该执行屏障操作,例如:
  if (barrier.await() == 0) {
     // log the completion of this iteration
   }
CyclicBarrier(int parties)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作

CyclicBarrier(int parties, Runnable barrierAction)
          创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。

await()
          在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。
await(long timeout, TimeUnit unit)
          在所有参与者都已经在此屏障上调用 await 方法之前,将一直等待。
getNumberWaiting()
          返回当前在屏障处等待的参与者数目。
getParties()
          返回要求启动此 barrier 的参与者数目。
isBroken()
          查询此屏障是否处于损坏状态。
reset()
          将屏障重置为其初始状态。
如果在线程处于等待状态时 barrier 被 reset(),或者在调用 await 时 barrier 被损坏,抑或任意一个线程正处于等待状态,则抛出 BrokenBarrierException 异常。
如果任何线程在等待时被 中断,则其他所有等待线程都将抛出 BrokenBarrierException 异常,并将 barrier 置于损坏状态。
如果当前线程是最后一个将要到达的线程,并且构造方法中提供了一个非空的屏障操作,则在允许其他线程继续运行之前,当前线程将运行该操作。如果在执行屏障操作过程中发生异常,则该异常将传播到当前线程中,并将 barrier 置于损坏状态。
返回:
到达的当前线程的索引,其中,索引 getParties() - 1 指示将到达的第一个线程,零指示最后一个到达的线程。
抛出:
InterruptedException - 如果当前线程在等待时被中断
BrokenBarrierException - 如果另一个 线程在当前线程等待时被中断,或者重置了 barrier,或者在调用 await 时 barrier 被损坏,抑或由于异常而导致屏障操作(如果存在)失败。

public void reset()
将屏障重置为其初始状态。如果所有参与者目前都在屏障处等待,则它们将返回,同时抛出一个 BrokenBarrierException。注意,在由于其他原因造成损坏之后,实行重置可能会变得很复杂;此时需要使用其他方式重新同步线程,并选择其中一个线程来执行重置。与为后续使用创建一个新 barrier 相比,这种方法可能更好一些。
CyclicBarrier 和CountDownLatch区别:
CountDownLatch就像一扇门的锁,比如我这门在10把钥匙才能打开,那么现在有十个线程过来了,十个人各自做自己的事,等到第十个人到达,这个门就打了,然后才执行await()后面的事情.
CyclicBarrier就像一个公共屏障点,比如我这个公共屏障点需要十个线程,那么,只有当十个线程都到达的时候,公共屏障点的方法就会执行,然后才会执行await()后面的事情
官方解释:
CountDownLatch:一个对同步有帮助的类,它允许一个或多个线程等待只到这组操作在其他线程全部完成
CyclicBarrier: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(common barrier point).
看官方解释差异性并不大.有些有整些乱七八糟的例子,真是汗了。
功能差差异不大,实现方式不同,countdown使用锁的机制,采用state信号量来维护他的线程数,CountDown采用递减的模式,当CountDown为0时,表示锁全部大开,大家从await()的地方进入.[基于Sync]
CyclicBarrier采用的递减的模式,当count 为0时,表示全部线程到达点,大家从await()的地方进入,它不需要调用countDown,它是采用await()自动维护其count[基于ReentrantLock]
当然其应用场景不同,比如在线程内部,我需要采用同步,那么我可以使用CountDown,然后await().
也可以采用CyclicBarrier的await().但是如果我要线程外部呢,我在所有工作都完成,然后我执行汇报给我的动作,那么在线程内部只需要计数countDown,然后在外部await()就可以了。如果线程间不需要互相等待,只是大家到某一个地点,然后再执行一个动作,那么采用countDown.
如果线程间需要互相等待,比如只有当所有人都到达时才执行一步,然后接下去又有一个逻辑….在屏障点需要执行其他逻辑等,那么采用CyclicBarrier,当然采用countDown也可以的,只是麻烦了一点.

从理论上来讲,CyclicBarrier可以实现同步实现机制,而不仅仅是一把锁。
以下是实例:
package org.cyclicbarrier;

import java.util.concurrent.CyclicBarrier;

public class Driver {

		  public static  void main(String args[]) throws InterruptedException {
			  final int N= 10;
			    boolean flag = false;
			  CyclicBarrier cyclic = new CyclicBarrier(
						N,
						new AnonSystem(flag,N)

				);//设置屏障点,主要是为了执行这个方法
		      for (int i = 0; i < N; ++i){ // create and start threads
		    	  print("工人"+i+"到了..");
		        new Thread(new Worker(cyclic,"工人"+i)).start();
		      }
		    }

		private static void print(String message) {
			// TODO Auto-generated method stub
			System.out.println(message);
		}
}


这是很简单的功能,我是项目经理,当员工全部到场了通知我一下,员工完成任务的时候也通知我一下.
package org.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Worker implements Runnable {

	private String worker;
	private final CyclicBarrier cyclic;

	Worker(CyclicBarrier cyclic,String worker) {
		this.cyclic = cyclic;
		this.worker = worker;
	}

	public void run() {
		try {
			cyclic.await();
			doWork();
			cyclic.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



	}

	void doWork() {
		System.out.println(worker+":劳动完成");
	}
}


大家一起到达,一起工作。

package org.cyclicbarrier;

public class AnonSystem implements Runnable{

	boolean flag;
	int N;
	public AnonSystem(boolean flag,int N){
		this.flag=flag;
		this.N=N;
	}
	public void run() {
		// TODO Auto-generated method stub
		if(flag){
			system("经理:[工人"+N+"个,已经完成工作]");
		}else{
			system("经理:[工人"+N+"个,已经到了]");
			flag = true;
		}
	}

		private void system(String str) {
			System.out.println(str);
		}
	}



工人到达和完成工作发通知.
1
0
分享到:
评论

相关推荐

    CountDownLatch和CyclicBarrier用法实例大全

    在Java并发编程中,CountDownLatch和CyclicBarrier是两种非常重要的同步工具类,它们用于协调多个线程间的协作。这两个工具都是在`java.util.concurrent`包下,是Java并发库的重要组成部分。 **CountDownLatch** ...

    CyclicBarrier的用法

    在Java多线程编程中,`CyclicBarrier`是一个非常重要的同步工具类,它允许一组线程等待其他线程到达某个屏障点后再一起继续执行。这个屏障点就是我们所说的“循环栅栏”,顾名思义,它就像一个旋转门,所有线程必须...

    CyclicBarrier的使用以及注意事项

    CyclicBarrier的使用以及注意事项

    CyclicBarrier,reentrantlock,condition模拟抢票

    用CyclicBarrier,reentrantlock,condition来完成同时购买,同步购买的功能 JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票) http://blog.csdn.net/crazyzxljing0621/article/details/77891620

    Java中的CountDownLatch与CyclicBarrier:深入理解与应用实践

    在Java的并发编程中,CountDownLatch和CyclicBarrier是两个非常重要的同步工具,它们用于协调多个线程的执行顺序。本文将详细介绍CountDownLatch和CyclicBarrier的工作原理、使用场景以及如何在实际项目中应用它们。...

    CyclicBarrier用法.docx

    CyclicBarrier是Java并发编程中一个非常重要的工具类,它属于java.util.concurrent包,主要用于多线程间的协作,尤其在需要多个线程等待彼此完成特定任务后才能继续执行的场景中发挥着关键作用。CyclicBarrier的名字...

    Java中的CyclicBarrier类最全讲义

    # Java中的CyclicBarrier类最全讲义 ## 1. 简介 ### 1.1 并发编程与线程协作 在现代软件开发中,特别是高性能计算领域,利用多核处理器的能力变得至关重要。为了充分利用这些硬件资源,程序员们开始广泛采用并发...

    JAVA CyclicBarrier类详解.docx

    《JAVA CyclicBarrier类详解》 CyclicBarrier是Java并发包(java.util.concurrent)中一个重要的同步辅助类,它的主要作用在于协调多个线程之间的协作,使得这些线程能够一起到达一个公共的“集结点”(称为屏障点...

    28 人齐了,一起行动—CyclicBarrier详解.pdf

    CyclicBarrier 是 Java 并发库中的一种同步工具类,用于协调多个线程之间的协作,使得它们能够一起开始某个计算任务或操作。它的名称“CyclicBarrier”来源于它具有可重用的特点,即当所有等待的线程都达到指定的...

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴 java并发编程中CountDownLatch和CyclicBarrier是两个非常重要的线程控制和调度工具,经常被用于解决多线程程序设计中的线程等待问题。本文将对...

    Java并发系列之CyclicBarrier源码分析

    Java并发系列之CyclicBarrier源码分析 CyclicBarrier是Java并发系列中的一种同步工具类,用于实现一组线程相互等待。当所有线程都到达某个屏障点后,再进行后续的操作。下面是对CyclicBarrier源码的详细分析。 ...

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

    在Java并发编程中,CountDownLatch和CyclicBarrier是两种非常重要的同步工具,用于协调多个线程之间的交互。它们都属于java.util.concurrent包下的类,为多线程编程提供了强大的支持。 **CountDownLatch** 是一个...

    CountDownLatch 和 CyclicBarrier 的运用(含AQS详解)

    ### CountDownLatch 和 CyclicBarrier 的运用(含AQS详解) #### CountDownLatch **定义与特点:** CountDownLatch 是 Java 并发包中的一个重要组件,它主要用于解决“一个或多个线程等待其他线程完成任务”的问题。...

    Java并发实例之CyclicBarrier的使用

    Java并发实例之CyclicBarrier的使用 CyclicBarrier是Java中的一种多线程并发控制实用工具,和CountDownLatch非常类似,它也可以实现线程间的计数等待,但是它的功能比CountDownLatch更加复杂且强大。CyclicBarrier...

    Java并发编程(CyclicBarrier)实例详解

    Java并发编程(CyclicBarrier)实例详解 Java并发编程(CyclicBarrier)实例详解主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,...

    CyclicBarrier(处理方案示例).md

    CyclicBarrier(处理方案示例).md

    java多线程之CyclicBarrier的使用方法

    Java多线程之CyclicBarrier的使用方法 Java多线程之CyclicBarrier的使用方法是Java多线程编程中的一种同步机制,用于实现多个线程之间的同步协作。CyclicBarrier是Java 5中引入的一种同步机制,用于让多个线程等待...

    java.CyclicBarrier(解决方案).md

    java.CyclicBarrier(解决方案).md

    Java中CyclicBarrier的用法分析

    Java中的`CyclicBarrier`是一个同步辅助类,它允许一组线程互相等待,直到所有线程都到达一个公共的屏障点。这个屏障点就像一个交通信号灯,只有当所有的车辆(线程)都到达了交叉口,信号灯才会变为绿灯,允许它们...

Global site tag (gtag.js) - Google Analytics