8029890: java/lang/management/ThreadMXBean/ThreadBlockedCount.java fails: Blocked thread has 4 blocked counts. Expected 3
authorjbachorik
Wed, 18 Dec 2013 10:58:50 +0100
changeset 22061 938534ee7a37
parent 22060 cd4f9d7dbeda
child 22062 175604b1209f
8029890: java/lang/management/ThreadMXBean/ThreadBlockedCount.java fails: Blocked thread has 4 blocked counts. Expected 3 Reviewed-by: sla
jdk/test/java/lang/management/ThreadMXBean/ThreadBlockedCount.java
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadBlockedCount.java	Wed Dec 18 08:41:46 2013 +0000
+++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadBlockedCount.java	Wed Dec 18 10:58:50 2013 +0100
@@ -26,56 +26,55 @@
  * @bug     4530538
  * @summary Basic unit test of ThreadInfo.getBlockedCount()
  * @author  Alexei Guibadoulline and Mandy Chung
+ * @author  Jaroslav Bachorik
  *
- * @build ThreadExecutionSynchronizer
  * @run main ThreadBlockedCount
  */
 
 import java.lang.management.*;
+import java.util.concurrent.Phaser;
 
 public class ThreadBlockedCount {
     final static long EXPECTED_BLOCKED_COUNT = 3;
     final static int  DEPTH = 10;
-    private static ThreadMXBean mbean
+    private static final ThreadMXBean mbean
         = ManagementFactory.getThreadMXBean();
 
-    private static Object a = new Object();
-    private static Object b = new Object();
-    private static Object c = new Object();
-    private static boolean aNotified = false;
-    private static boolean bNotified = false;
-    private static boolean cNotified = false;
-    private static Object blockedObj1 = new Object();
-    private static Object blockedObj2 = new Object();
-    private static Object blockedObj3 = new Object();
-    private static volatile boolean testFailed = false;
+    private static final Object a = new Object();
+    private static final Object b = new Object();
+    private static final Object c = new Object();
+
+    private static final Object blockedObj1 = new Object();
+    private static final Object blockedObj2 = new Object();
+    private static final Object blockedObj3 = new Object();
+    private static volatile boolean testOk = false;
     private static BlockingThread blocking;
     private static BlockedThread blocked;
-    private static ThreadExecutionSynchronizer thrsync;
 
 
 
     public static void main(String args[]) throws Exception {
-        // Create the BlockingThread before BlockedThread
-        // to make sure BlockingThread enter the lock before BlockedThread
-        thrsync = new ThreadExecutionSynchronizer();
+        final Phaser p = new Phaser(2);
 
-        blocking = new BlockingThread();
+        blocking = new BlockingThread(p);
         blocking.start();
 
-        blocked = new BlockedThread();
+        blocked = new BlockedThread(p);
         blocked.start();
 
         try {
             blocking.join();
-            blocked.join();
+
+            testOk = checkBlocked();
+            p.arriveAndAwaitAdvance(); // #5
+
         } catch (InterruptedException e) {
             System.err.println("Unexpected exception.");
             e.printStackTrace(System.err);
             throw e;
         }
 
-        if (testFailed) {
+        if (!testOk) {
             throw new RuntimeException("TEST FAILED.");
         }
         System.out.println("Test passed.");
@@ -83,29 +82,19 @@
 
 
     static class BlockedThread extends Thread {
-        // NOTE: We can't use a.wait() here because wait() call is counted
-        // as blockedCount.  Instead, we use a boolean flag and sleep.
-        //
+        private final Phaser p;
+
+        BlockedThread(Phaser p) {
+            super("BlockedThread");
+            this.p = p;
+        }
+
         public void run() {
-            // wait Blocking thread
-            thrsync.signal();
+            p.arriveAndAwaitAdvance(); // #1
 
             // Enter lock a without blocking
             synchronized (a) {
-                // wait until BlockingThread holds blockedObj1
-                while (!aNotified) {
-                    try {
-                        Thread.sleep(50);
-                    } catch (InterruptedException e) {
-                        System.err.println("Unexpected exception.");
-                        e.printStackTrace(System.err);
-                        testFailed = true;
-                        break;
-                    }
-                }
-
-                // signal BlockingThread.
-                thrsync.signal();
+                p.arriveAndAwaitAdvance(); // #2
 
                 // Block to enter blockedObj1
                 // blockedObj1 should be owned by BlockingThread
@@ -114,25 +103,10 @@
                 }
             }
 
-            // signal BlockingThread.
-            thrsync.signal();
-
             // Enter lock a without blocking
             synchronized (b) {
                 // wait until BlockingThread holds blockedObj2
-                while (!bNotified) {
-                    try {
-                        Thread.sleep(50);
-                    } catch (InterruptedException e) {
-                        System.err.println("Unexpected exception.");
-                        e.printStackTrace(System.err);
-                        testFailed = true;
-                        break;
-                    }
-                }
-
-                // signal BlockingThread.
-                thrsync.signal();
+                p.arriveAndAwaitAdvance(); // #3
 
                 // Block to enter blockedObj2
                 // blockedObj2 should be owned by BlockingThread
@@ -141,25 +115,10 @@
                 }
             }
 
-            // signal BlockingThread.
-            thrsync.signal();
-
             // Enter lock a without blocking
             synchronized (c) {
                 // wait until BlockingThread holds blockedObj3
-                while (!cNotified) {
-                    try {
-                        Thread.sleep(50);
-                    } catch (InterruptedException e) {
-                        System.err.println("Unexpected exception.");
-                        e.printStackTrace(System.err);
-                        testFailed = true;
-                        break;
-                    }
-                }
-
-                // signal BlockingThread.
-                thrsync.signal();
+                p.arriveAndAwaitAdvance(); // #4
 
                 // Block to enter blockedObj3
                 // blockedObj3 should be owned by BlockingThread
@@ -168,35 +127,23 @@
                 }
             }
 
-            // wait for the thread stats to be updated for 10 seconds
-            for (int i = 0; i < 100; i++) {
-                if (getBlockedCount() == EXPECTED_BLOCKED_COUNT) {
-                    return;
-                }
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                    System.err.println("Unexpected exception.");
-                    e.printStackTrace(System.err);
-                    testFailed = true;
-                    return;
-                }
-            }
-            long count = getBlockedCount();
-            if (count != EXPECTED_BLOCKED_COUNT) {
-                System.err.println("TEST FAILED: Blocked thread has " + count +
-                                    " blocked counts. Expected " +
-                                    EXPECTED_BLOCKED_COUNT);
-                testFailed = true;
-            }
+            // wait for the main thread to check the blocked count
+            p.arriveAndAwaitAdvance(); // #5
+            // ... and we can leave now
         } // run()
-    } // BlockingThread
+    } // BlockedThread
 
     static class BlockingThread extends Thread {
-        private void waitForSignalToRelease() {
+        private final Phaser p;
 
+        BlockingThread(Phaser p) {
+            super("BlockingThread");
+            this.p = p;
+        }
+
+        private void waitForBlocked() {
             // wait for BlockedThread.
-            thrsync.waitForSignal();
+            p.arriveAndAwaitAdvance();
 
             boolean threadBlocked = false;
             while (!threadBlocked) {
@@ -206,7 +153,7 @@
                 } catch (InterruptedException e) {
                     System.err.println("Unexpected exception.");
                     e.printStackTrace(System.err);
-                    testFailed = true;
+                    testOk = false;
                     break;
                 }
                 ThreadInfo info = mbean.getThreadInfo(blocked.getId());
@@ -215,44 +162,55 @@
         }
 
         public void run() {
-            // wait for BlockedThread.
-            thrsync.waitForSignal();
+            p.arriveAndAwaitAdvance(); // #1
 
             synchronized (blockedObj1) {
                 System.out.println("BlockingThread attempts to notify a");
-                aNotified = true;
-                waitForSignalToRelease();
+                waitForBlocked(); // #2
             }
 
-            // wait for BlockedThread.
-            thrsync.waitForSignal();
-
             // block until BlockedThread is ready
             synchronized (blockedObj2) {
                 System.out.println("BlockingThread attempts to notify b");
-                bNotified = true;
-                waitForSignalToRelease();
+                waitForBlocked(); // #3
             }
 
-            // wait for BlockedThread.
-            thrsync.waitForSignal();
-
             // block until BlockedThread is ready
             synchronized (blockedObj3) {
                 System.out.println("BlockingThread attempts to notify c");
-                cNotified = true;
-                waitForSignalToRelease();
+                waitForBlocked(); // #4
             }
 
         } // run()
-    } // BlockedThread
+    } // BlockingThread
 
     private static long getBlockedCount() {
         long count;
         // Check the mbean now
-        ThreadInfo ti = mbean.getThreadInfo(Thread.currentThread().
-                getId());
+        ThreadInfo ti = mbean.getThreadInfo(blocked.getId());
         count = ti.getBlockedCount();
         return count;
     }
+
+    private static boolean checkBlocked() {
+        // wait for the thread stats to be updated for 10 seconds
+        long count = -1;
+        for (int i = 0; i < 100; i++) {
+            count = getBlockedCount();
+            if (count == EXPECTED_BLOCKED_COUNT) {
+                return true;
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                System.err.println("Unexpected exception.");
+                e.printStackTrace(System.err);
+                return false;
+            }
+        }
+        System.err.println("TEST FAILED: Blocked thread has " + count +
+                            " blocked counts. Expected " +
+                            EXPECTED_BLOCKED_COUNT);
+        return false;
+    }
 }