JDK-7067749 : Phaser.arrive() throws IllegalStateException
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2011-07-15
  • Updated: 2011-07-19
  • Resolved: 2011-07-18
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.
JDK 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
SYNOPSIS
--------
Phaser.arrive() throws IllegalStateException

OPERATING SYSTEM
----------------
Tested on Windows and Linux

FULL JDK VERSION
----------------
JDK 7 (b128 onwards)

PROBLEM DESCRIPTION from LICENSEE
---------------------------------
The attached testcase throws an IllegalStateException when run against JDK 7 b128 or later. This appears to be caused by a timing issue.

There were two changes in the concurrency code in b128:

7011857: java/util/concurrent/Phaser/FickleRegister.java fails on solaris-sparc
7005424: Resync java.util.concurrent classes with Dougs CVS - Jan 2011

REPRODUCTION INSTRUCTIONS
-------------------------
Compile and run the attached testcase.

Expected behaviour
Should run forever without throwing an Exception

Observed behaviour
An Exception is thrown shortly after the testcase starts, for example:

java.lang.IllegalStateException: Attempted arrival of unregistered party for java.util.concurrent.Phaser@471e30[phase =
197942 parties = 2 arrived = 2]
        at java.util.concurrent.Phaser.doArrive(Phaser.java:389)
        at java.util.concurrent.Phaser.arrive(Phaser.java:622)
        at PhaserTest$PhaserTestHelper.run(PhaserTest.java:38)
        at java.lang.Thread.run(Thread.java:732)

TESTCASE
--------
import java.util.concurrent.Phaser;

public class PhaserTest {
    private Phaser testPhaser = new Phaser();

    public void doTest() {
        Thread[] helpers = new Thread[2];

        for (int i = 0; i < helpers.length; i++) {
            Thread phaserHelper = new Thread(new PhaserTestHelper(testPhaser));
            phaserHelper.setName("Thread" + i);
            helpers[i] = phaserHelper;
        }

        for (int i = 0; i < helpers.length; i++) {
            helpers[i].start();
        }

        while (true) {
            if (testPhaser.isTerminated())
                break;
        }
    }

    public class PhaserTestHelper implements Runnable {
        private Phaser myPhaser;

        public PhaserTestHelper(Phaser phaser) {
            myPhaser = phaser;
            myPhaser.register();
        }

        public void run() {        
            while (true) {
                try {
                    if (myPhaser.isTerminated())
                        break;
                    myPhaser.arrive();
                } catch (IllegalStateException ise) {
                    ise.printStackTrace();
                    myPhaser.forceTermination();
                    break;
                }
            }
        }

    }

    public static void main(String[] args){
        PhaserTest problem = new PhaserTest();
        problem.doTest();
    }
}

Comments
EVALUATION The problem with the test case is that you can not have more parties arrive at the Phaser in a given phase than are registered. So a loop such as: while (true) { try { if (myPhaser.isTerminated()) break; myPhaser.arrive(); } catch (IllegalStateException ise) { ise.printStackTrace(); myPhaser.forceTermination(); break; } } is invalid without addition coordination to ensure arrive() is only invoked once per phase. (Assuming N threads execute the loop and N parties are registered on the phaser)
19-07-2011

EVALUATION Looks like a duplicate of 7058828.
18-07-2011