author | jbachorik |
Wed, 15 Apr 2015 09:38:45 +0200 | |
changeset 30353 | d831fae73de9 |
parent 30352 | 551e7993450a |
child 30354 | ca83b4cae363 |
--- a/jdk/test/java/lang/management/ThreadMXBean/Semaphore.java Mon Apr 13 09:43:12 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @bug 4530538 - * @summary A semaphore utility class. - * @author Mandy Chung - */ - -public class Semaphore { - private Object go = new Object(); - private int semaCount; - private int waiters = 0; - - public Semaphore() { - semaCount = 0; - } - - public Semaphore(int initialCount) { - semaCount = initialCount; - } - - public void semaP() { - synchronized (go) { - waiters++; - while (semaCount == 0) { - try { - go.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new InternalError(); - } - } - semaCount--; - waiters--; - } - } - public void semaV() { - synchronized (go) { - semaCount++; - go.notify(); - } - } - - public int getWaiterCount() { - synchronized (go) { - return waiters; - } - } - - public Object getLock() { - return go; - } -}
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java Mon Apr 13 09:43:12 2015 +0200 +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java Wed Apr 15 09:38:45 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,25 +28,26 @@ * ThreadInfo.getThreadState() * @author Mandy Chung * - * @run build Semaphore Utils + * @run build Utils * @run main ThreadStackTrace */ import java.lang.management.*; +import java.util.concurrent.Phaser; public class ThreadStackTrace { - private static ThreadMXBean mbean + private static final ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); private static boolean notified = false; - private static Object lockA = new Object(); - private static Object lockB = new Object(); + private static final Object lockA = new Object(); + private static final Object lockB = new Object(); private static volatile boolean testFailed = false; - private static String[] blockedStack = {"run", "test", "A", "B", "C", "D"}; - private static int bsDepth = 6; - private static int methodB = 4; - private static String[] examinerStack = {"run", "examine1", "examine2"}; - private static int esDepth = 3; - private static int methodExamine1= 2; + private static final String[] blockedStack = {"run", "test", "A", "B", "C", "D"}; + private static final int bsDepth = 6; + private static final int methodB = 4; + private static final String[] examinerStack = {"run", "examine1", "examine2"}; + private static final int esDepth = 3; + private static final int methodExamine1= 2; private static void checkNullThreadInfo(Thread t) throws Exception { ThreadInfo ti = mbean.getThreadInfo(t.getId()); @@ -69,8 +70,10 @@ trace = true; } - Examiner examiner = new Examiner("Examiner"); - BlockedThread blocked = new BlockedThread("BlockedThread"); + final Phaser p = new Phaser(2); + + Examiner examiner = new Examiner("Examiner", p); + BlockedThread blocked = new BlockedThread("BlockedThread", p); examiner.setThread(blocked); checkNullThreadInfo(examiner); @@ -79,8 +82,8 @@ // Start the threads and check them in Blocked and Waiting states examiner.start(); - // block until examiner begins doing its real work - examiner.waitForStarted(); + // #1 - block until examiner begins doing its real work + p.arriveAndAwaitAdvance(); System.out.println("Checking stack trace for the examiner thread " + "is waiting to begin."); @@ -145,35 +148,11 @@ } static class BlockedThread extends Thread { - private Semaphore handshake = new Semaphore(); - - BlockedThread(String name) { - super(name); - } - boolean hasWaitersForBlocked() { - return (handshake.getWaiterCount() > 0); - } - - void waitUntilBlocked() { - handshake.semaP(); + private final Phaser phaser; - // give a chance for the examiner thread to really wait - Utils.goSleep(20); - } - - void waitUntilLockAReleased() { - handshake.semaP(); - - // give a chance for the examiner thread to really wait - Utils.goSleep(50); - } - - private void notifyWaiter() { - // wait until the examiner waits on the semaphore - while (handshake.getWaiterCount() == 0) { - Utils.goSleep(20); - } - handshake.semaV(); + BlockedThread(String name, Phaser phaser) { + super(name); + this.phaser = phaser; } private void test() { @@ -185,25 +164,24 @@ private void B() { C(); - // notify the examiner about to block on lockB - notifyWaiter(); + // #4 - notify the examiner about to block on lockB + phaser.arriveAndAwaitAdvance(); - synchronized (lockB) { - }; + synchronized (lockB) {}; } private void C() { D(); } private void D() { - // Notify that examiner about to enter lockA - notifyWaiter(); + // #2 - Notify that examiner about to enter lockA + phaser.arriveAndAwaitAdvance(); synchronized (lockA) { notified = false; while (!notified) { try { - // notify the examiner about to release lockA - notifyWaiter(); + // #3 - notify the examiner about to release lockA + phaser.arriveAndAwaitAdvance(); // Wait and let examiner thread check the mbean lockA.wait(); } catch (InterruptedException e) { @@ -216,6 +194,7 @@ } } + @Override public void run() { test(); } // run() @@ -223,28 +202,17 @@ static class Examiner extends Thread { private static BlockedThread blockedThread; - private Semaphore handshake = new Semaphore(); + private final Phaser phaser; - Examiner(String name) { + Examiner(String name, Phaser phaser) { super(name); + this.phaser = phaser; } public void setThread(BlockedThread thread) { blockedThread = thread; } - public synchronized void waitForStarted() { - // wait until the examiner is about to block - handshake.semaP(); - - // wait until the examiner is waiting for blockedThread's notification - while (!blockedThread.hasWaitersForBlocked()) { - Utils.goSleep(50); - } - // give a chance for the examiner thread to really wait - Utils.goSleep(20); - } - private Thread itself; private void examine1() { synchronized (lockB) { @@ -254,8 +222,9 @@ Utils.checkThreadState(itself, Thread.State.RUNNABLE); checkStack(itself, examinerStack, methodExamine1); - // wait until blockedThread is blocked on lockB - blockedThread.waitUntilBlocked(); + // #4 - wait until blockedThread is blocked on lockB + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.BLOCKED); System.out.println("Checking stack trace for " + "BlockedThread - should be blocked on lockB."); @@ -271,15 +240,12 @@ private void examine2() { synchronized (lockA) { - // wait until main thread gets signalled of the semaphore - while (handshake.getWaiterCount() == 0) { - Utils.goSleep(20); - } - - handshake.semaV(); // notify the main thread + // #1 - examiner ready to do the real work + phaser.arriveAndAwaitAdvance(); try { - // Wait until BlockedThread is about to block on lockA - blockedThread.waitUntilBlocked(); + // #2 - Wait until BlockedThread is about to block on lockA + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.BLOCKED); System.out.println("Checking examiner's its own stack trace"); Utils.checkThreadState(itself, Thread.State.RUNNABLE); @@ -297,9 +263,10 @@ } } - // release lockA and let BlockedThread to get the lock + // #3 - release lockA and let BlockedThread to get the lock // and wait on lockA - blockedThread.waitUntilLockAReleased(); + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.WAITING); synchronized (lockA) { try { @@ -321,6 +288,7 @@ Utils.goSleep(50); } // examine2() + @Override public void run() { itself = Thread.currentThread(); examine1();