JDK-6366811 : CyclicBarrier behaviour incorrect if interruption occurs during barrier "trip"
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-12-23
  • Updated: 2010-04-04
  • Resolved: 2006-01-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u8Fixed 6 b69Fixed
Related Reports
Relates :  
Description
The CyclicBarrier specification states that it uses a "fast-fail all or none breakage model for failed synchronization attempts" (i.e attempts that are interrupted or timed-out). The current behaviour does not meet this specification. If the last thread needed at the barrier arrives and commences to "trip" the barrier, and a waiting thread is then interrupted, then if that interrupted thread encounters InterruptedException from the internal Condition.await(), it will break the barrier and rethrow the InterruptedException - which is contrary to the "all or none" breakage semantics.

Further, at the time the interrupted thread breaks the barrier, the generation of the barrier has already been advanced, so it is the next generation that gets broken by this threads actions. This means the next group of threads to wait on the barrier will fail for no obvious reason, given that a long time could elapse between uses of the barrier.

Comments
SUGGESTED FIX --- /u/martin/ws/mustang/src/share/classes/java/util/concurrent/CyclicBarrier.java 2005-12-04 14:55:05.651137000 -0800 +++ /u/martin/ws/holmes/src/share/classes/java/util/concurrent/CyclicBarrier.java 2006-01-03 12:49:53.981494000 -0800 @@ -115,7 +115,6 @@ */ private static class Generation { boolean broken = false; - boolean tripped = false; } /** The lock for guarding barrier entry */ @@ -142,7 +141,6 @@ */ private void nextGeneration() { // signal completion of last generation - generation.tripped = true; trip.signalAll(); // set up next generation count = parties; @@ -202,14 +200,21 @@ else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { + if (g == generation && ! g.broken) { breakBarrier(); throw ie; + } else { + // We're about to finish waiting even if we had not + // been interrupted, so this interrupt is deemed to + // "belong" to subsequent execution. + Thread.currentThread().interrupt(); + } } if (g.broken) throw new BrokenBarrierException(); - if (g.tripped) + if (g != generation) return index; if (timed && nanos <= 0L) { @@ -270,7 +275,7 @@ * * <p>If the current thread is not the last to arrive then it is * disabled for thread scheduling purposes and lies dormant until - * one of following things happens: + * one of the following things happens: * <ul> * <li>The last thread arrives; or * <li>Some other thread {@link Thread#interrupt interrupts} the current
03-01-2006

EVALUATION Two refinements: - the "tripped" field can be eliminated, since g.tripped is equivalent to "generation == g" - If an InterruptedException is caught when the await would have ended for some other reason anyways, the interrupt bit should be set on again, and the wait ended for the other reason, possibly throwing BrokenBarrierException. This leads to slightly more predictable behavior. (It's still not a good idea to try to break a CyclicBarrier by interrupting more than one thread)
03-01-2006

SUGGESTED FIX When the interrupted thread catches the InterruptedException it only breaks the barrier and rethrows the IE if the current generation has not been tripped. Otherwise it simply reasserts the interrupt state of the thread.
23-12-2005

EVALUATION This bug has been analysed and confirmed by the jsr166 EG
23-12-2005