|
|||||||||
摘要: 嵌套 | 字段 | 构造方法 | 方法 | 详细信息: 字段 | 构造方法 | 方法 |
java.util.concurrent
类 CyclicBarrier
java.lang.Object java.util.concurrent.CyclicBarrier
-
public class CyclicBarrier
- extends Object
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable
命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
示例用法:下面是一个在并行分解设计中使用 barrier 的例子:
class Solver { final int N; final float[][] data; final CyclicBarrier barrier; class Worker implements Runnable { int myRow; Worker(int row) { myRow = row; } public void run() { while (!done()) { processRow(myRow); try { barrier.await(); } catch (InterruptedException ex) { return; } catch (BrokenBarrierException ex) { return; } } } } public Solver(float[][] matrix) { data = matrix; N = matrix.length; barrier = new CyclicBarrier(N, new Runnable() { public void run() { mergeRows(...); } }); for (int i = 0; i < N; ++i) new Thread(new Worker(i)).start(); waitUntilDone(); } }在这个例子中,每个 worker 线程处理矩阵的一行,在处理完所有的行之前,该线程将一直在屏障处等待。处理完所有的行之后,将执行所提供的
Runnable
屏障操作,并合并这些行。如果合并者确定已经找到了一个解决方案,那么 done() 将返回 true,所有的 worker 线程都将终止。
如果屏障操作在执行时不依赖于正挂起的线程,则线程组中的任何线程在获得释放时都能执行该操作。为方便此操作,每次调用 await()
都将返回能到达屏障处的线程的索引。然后,您可以选择哪个线程应该执行屏障操作,例如:
if (barrier.await() == 0) { // log the completion of this iteration }
对于失败的同步尝试,CyclicBarrier 使用了一种快速失败的、要么全部要么全不 (all-or-none) 的破坏模式:如果因为中断、失败或者超时等原因,导致线程过早地离开了屏障点,那么其他所有线程(甚至是那些尚未从以前的 await()
中恢复的线程)也将通过 BrokenBarrierException
(如果它们几乎同时被中断,则用 InterruptedException)以反常的方式离开。
- 从以下版本开始:
- 1.5
- 另请参见:
-
CountDownLatch
构造方法摘要 | |
---|---|
CyclicBarrier(int parties) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。 |
|
CyclicBarrier(int parties, Runnable barrierAction) 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。 |
方法摘要 | |
---|---|
int |
await() 在所有 参与者 都已经在此 barrier 上调用 await 方法之前,将一直等待。 |
int |
await(long timeout, TimeUnit unit) 在所有 参与者 都已经在此屏障上调用 await 方法之前,将一直等待。 |
int |
getNumberWaiting() 返回当前在屏障处等待的参与者数目。 |
int |
getParties() 返回要求启动此 barrier 的参与者数目。 |
boolean |
isBroken() 查询此屏障是否处于损坏状态。 |
void |
reset() 将屏障重置为其初始状态。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
构造方法详细信息 |
---|
CyclicBarrier
public CyclicBarrier(int parties, Runnable barrierAction)
-
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。
- 参数:
-
parties
- 在启动 barrier 前必须调用await()
的线程数。 -
barrierAction
- 在启动 barrier 时执行的命令;如果不执行任何操作,则该参数为 null。 - 抛出:
-
IllegalArgumentException
- 如果 parties 小于 1。
CyclicBarrier
public CyclicBarrier(int parties)
-
创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在每个 barrier 上执行预定义的操作。
- 参数:
-
parties
- 在启动 barrier 前必须调用await()
的线程数。 - 抛出:
-
IllegalArgumentException
- 如果 parties 小于 1。
方法详细信息 |
---|
getParties
public int getParties()
- 返回要求启动此 barrier 的参与者数目。
-
- 返回:
- 要求启动此 barrier 的参与者数目。
await
public int await() throws InterruptedException, BrokenBarrierException
-
在所有
参与者
都已经在此 barrier 上调用 await 方法之前,将一直等待。如果当前线程不是将到达的最后一个线程,出于调度目的,将禁用它,且在发生以下情况之一前,该线程将一直处于休眠状态:
- 最后一个线程到达;或者
- 其他某个线程
中断
当前线程;或者 - 其他某个线程
中断
另一个等待线程;或者 - 其他某个线程在等待 barrier 时超时;或者
- 其他某个线程在此 barrier 上调用
reset()
。
如果当前线程:
- 在进入此方法时已经设置了该线程的中断状态;或者
- 在等待时被
中断
InterruptedException
,并且清除当前线程的已中断状态。如果在线程处于等待状态时 barrier 被
reset()
,或者在调用 await 时 barrier被损坏
,抑或任意一个线程正处于等待状态,则抛出BrokenBarrierException
异常。如果任何线程在等待时被
中断
,则其他所有等待线程都将抛出BrokenBarrierException
异常,并将 barrier 置于损坏状态。如果当前线程是最后一个将要到达的线程,并且构造方法中提供了一个非空的屏障操作,则在允许其他线程继续运行之前,当前线程将运行该操作。如果在执行屏障操作过程中发生异常,则该异常将传播到当前线程中,并将 barrier 置于损坏状态。
-
- 返回:
-
到达的当前线程的索引,其中,索引
getParties()
- 1 指示将到达的第一个线程,零指示最后一个到达的线程。 - 抛出:
-
InterruptedException
- 如果当前线程在等待时被中断 -
BrokenBarrierException
- 如果另一个 线程在当前线程等待时被中断,或者重置了 barrier,或者在调用 await 时 barrier 被损坏,抑或由于异常而导致屏障操作(如果存在)失败。
await
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
-
在所有
参与者
都已经在此屏障上调用 await 方法之前,将一直等待。如果当前线程不是将到达的最后一个线程,出于调度目的,将禁用它,且在发生以下情况之一前,该线程将一直处于休眠状态:
- 最后一个线程到达;或者
- 超出指定的超时时间;或者
- 其他某个线程
中断
当前线程;或者 - 其他某个线程
中断
另一个等待线程;或者 - 其他某个线程在等待 barrier 时超时;或者
- 其他某个线程在此 barrier 上调用
reset()
。
如果当前线程:
- 在进入此方法时已经设置了该线程的中断状态;或者
- 在等待时被
中断
InterruptedException
,并且清除当前线程的已中断状态。如果超出指定的等待时间,则抛出
TimeoutException
异常。如果该时间小于或等于零,则此方法根本不会等待。如果在线程处于等待状态时 barrier 被
reset()
,或者在调用 await 时 barrier被损坏
,抑或任意一个线程正处于等待状态,则抛出BrokenBarrierException
异常。如果任何线程在等待时被
中断
,则其他所有等待线程都将抛出BrokenBarrierException
,并将屏障置于损坏状态。如果当前线程是最后一个将要到达的线程,并且构造方法中提供了一个非空的屏障操作,则在允许其他线程继续运行之前,当前线程将运行该操作。如果在执行屏障操作过程中发生异常,则该异常将传播到当前线程中,并将 barrier 置于损坏状态。
-
- 参数:
-
timeout
- 等待 barrier 的时间 -
unit
- 超时参数的时间单位 - 返回:
-
到达的当前线程的索引,其中,索引
getParties()
- 1 指示第一个将要到达的线程,零指示最后一个到达的线程。 - 抛出:
-
InterruptedException
- 如果当前线程在等待时被中断 -
TimeoutException
- 如果超出了指定的超时时间。 -
BrokenBarrierException
- 如果另一个 线程在当前线程等待时被中断,或者重置了 barrier,或者调用 await 时 barrier 被损坏,抑或由于异常而导致屏障操作(如果存在)失败。
isBroken
public boolean isBroken()
- 查询此屏障是否处于损坏状态。
-
- 返回:
- 如果因为构造或最后一次重置而导致中断或超时,从而使一个或多个参与者摆脱此 barrier,或者因为异常而导致某个屏障操作失败,则返回 true;否则返回 false。
reset
public void reset()
-
将屏障重置为其初始状态。如果所有参与者目前都在屏障处等待,则它们将返回,同时抛出一个
BrokenBarrierException
。注意,在由于其他原因造成损坏之后,实行重置可能会变得很复杂;此时需要使用其他方式重新同步线程,并选择其中一个线程来执行重置。与为后续使用创建一个新 barrier 相比,这种方法可能更好一些。 -
getNumberWaiting
public int getNumberWaiting()
- 返回当前在屏障处等待的参与者数目。此方法主要用于调试和断言。
-
- 返回:
-
当前阻塞在
await()
中的参与者数目。