org.elasticsearch.common.util.concurrent
Class ThreadBarrier
java.lang.Object
java.util.concurrent.CyclicBarrier
org.elasticsearch.common.util.concurrent.ThreadBarrier
public class ThreadBarrier
- extends java.util.concurrent.CyclicBarrier
A synchronization aid that allows a set of threads to all wait for each other
to reach a common barrier point. Barriers are useful in programs involving a
fixed sized party of threads that must occasionally wait for each other.
ThreadBarrier adds a cause to
BrokenBarrierException thrown by a CyclicBarrier.reset() operation defined
by CyclicBarrier.
Sample usage:
Barrier as a synchronization and Exception handling aid
Barrier as a trigger for elapsed notification events
class MyTestClass implements RemoteEventListener
{
final ThreadBarrier barrier;
class Worker implements Runnable
{
public void run()
{
barrier.await(); //wait for all threads to reach run
try
{
prepare();
barrier.await(); //wait for all threads to prepare
process();
barrier.await(); //wait for all threads to process
}
catch(Throwable t){
log("Worker thread caught exception", t);
barrier.reset(t);
}
}
}
public void testThreads() {
barrier = new ThreadBarrier(N_THREADS + 1);
for (int i = 0; i < N; ++i)
new Thread(new Worker()).start();
try{
barrier.await(); //wait for all threads to reach run
barrier.await(); //wait for all threads to prepare
barrier.await(); //wait for all threads to process
}
catch(BrokenBarrierException bbe) {
Assert.fail(bbe);
}
}
int actualNotificationCount = 0;
public synchronized void notify (RemoteEvent event) {
try{
actualNotificationCount++;
if (actualNotificationCount == EXPECTED_COUNT)
barrier.await(); //signal when all notifications arrive
// too many notifications?
Assert.assertFalse("Exceeded notification count",
actualNotificationCount > EXPECTED_COUNT);
}
catch(Throwable t) {
log("Worker thread caught exception", t);
barrier.reset(t);
}
}
public void testNotify() {
barrier = new ThreadBarrier(N_LISTENERS + 1);
registerNotification();
triggerNotifications();
//wait until either all notifications arrive, or
//until a MAX_TIMEOUT is reached.
barrier.await(MAX_TIMEOUT);
//check if all notifications were accounted for or timed-out
Assert.assertEquals("Notification count",
EXPECTED_COUNT, actualNotificationCount);
//inspect that the barrier isn't broken
barrier.inspect(); //throws BrokenBarrierException if broken
}
}
|
Method Summary |
int |
await()
|
int |
await(long timeout,
java.util.concurrent.TimeUnit unit)
|
void |
inspect()
Inspects if the barrier is broken. |
boolean |
isBroken()
Queries if this barrier is in a broken state. |
void |
reset(java.lang.Throwable cause)
Resets the barrier to its initial state. |
| Methods inherited from class java.util.concurrent.CyclicBarrier |
getNumberWaiting, getParties, reset |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
ThreadBarrier
public ThreadBarrier(int parties)
ThreadBarrier
public ThreadBarrier(int parties,
java.lang.Runnable barrierAction)
await
public int await()
throws java.lang.InterruptedException,
java.util.concurrent.BrokenBarrierException
- Overrides:
await in class java.util.concurrent.CyclicBarrier
- Throws:
java.lang.InterruptedException
java.util.concurrent.BrokenBarrierException
await
public int await(long timeout,
java.util.concurrent.TimeUnit unit)
throws java.lang.InterruptedException,
java.util.concurrent.BrokenBarrierException,
java.util.concurrent.TimeoutException
- Overrides:
await in class java.util.concurrent.CyclicBarrier
- Throws:
java.lang.InterruptedException
java.util.concurrent.BrokenBarrierException
java.util.concurrent.TimeoutException
reset
public void reset(java.lang.Throwable cause)
- Resets the barrier to its initial state. If any parties are
currently waiting at the barrier, they will return with a
BrokenBarrierException. Note that resets after
a breakage has occurred for other reasons can be complicated to
carry out; threads need to re-synchronize in some other way,
and choose one to perform the reset. It may be preferable to
instead create a new barrier for subsequent use.
- Parameters:
cause - The cause of the BrokenBarrierException
isBroken
public boolean isBroken()
- Queries if this barrier is in a broken state. Note that if
reset(Throwable) is invoked the barrier will remain broken, while
CyclicBarrier.reset() will reset the barrier to its initial state and
isBroken() will return false.
- Overrides:
isBroken in class java.util.concurrent.CyclicBarrier
- Returns:
true if one or more parties broke out of this barrier due
to interruption or timeout since construction or the last reset,
or a barrier action failed due to an exception; false
otherwise.- See Also:
inspect()
inspect
public void inspect()
throws java.util.concurrent.BrokenBarrierException
- Inspects if the barrier is broken. If for any reason, the barrier
was broken, a
BrokenBarrierException will be thrown. Otherwise,
would return gracefully.
- Throws:
java.util.concurrent.BrokenBarrierException - With a nested broken cause.