Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/management/ManagementFactory/ThreadMXBeanProxy.java
38828 views
/*1* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 5086470 6358247 719330226* @summary Test type conversion when invoking ThreadMXBean.dumpAllThreads27* through proxy.28*29* @author Mandy Chung30*31* @run main ThreadMXBeanProxy32*/3334import static java.lang.management.ManagementFactory.*;35import java.lang.management.*;36import java.util.*;37import java.util.concurrent.locks.*;38import java.util.concurrent.TimeUnit;39import java.io.*;40import javax.management.*;4142public class ThreadMXBeanProxy {43private static MBeanServer server =44ManagementFactory.getPlatformMBeanServer();45private static ThreadMXBean mbean;46static Mutex mutex = new Mutex();47static Object lock = new Object();48static MyThread thread = new MyThread();49public static void main(String[] argv) throws Exception {50mbean = newPlatformMXBeanProxy(server,51THREAD_MXBEAN_NAME,52ThreadMXBean.class);5354if (!mbean.isSynchronizerUsageSupported()) {55System.out.println("Monitoring of synchronizer usage not supported");56return;57}5859thread.setDaemon(true);60thread.start();6162// wait until myThread acquires mutex and lock owner is set.63while (!(mutex.isLocked() && mutex.getLockOwner() == thread)) {64try {65Thread.sleep(100);66} catch (InterruptedException e) {67throw new RuntimeException(e);68}69}7071long[] ids = new long[] { thread.getId() };7273// validate the local access74ThreadInfo[] infos = getThreadMXBean().getThreadInfo(ids, true, true);75if (infos.length != 1) {76throw new RuntimeException("Returned ThreadInfo[] of length=" +77infos.length + ". Expected to be 1.");78}79thread.checkThreadInfo(infos[0]);8081// validate the remote access82infos = mbean.getThreadInfo(ids, true, true);83if (infos.length != 1) {84throw new RuntimeException("Returned ThreadInfo[] of length=" +85infos.length + ". Expected to be 1.");86}87thread.checkThreadInfo(infos[0]);8889boolean found = false;90infos = mbean.dumpAllThreads(true, true);91for (ThreadInfo ti : infos) {92if (ti.getThreadId() == thread.getId()) {93thread.checkThreadInfo(ti);94found = true;95}96}9798if (!found) {99throw new RuntimeException("No ThreadInfo found for MyThread");100}101102System.out.println("Test passed");103}104105static class MyThread extends Thread {106public MyThread() {107super("MyThread");108}109public void run() {110synchronized (lock) {111mutex.lock();112Object o = new Object();113synchronized(o) {114try {115o.wait();116} catch (InterruptedException e) {117throw new RuntimeException(e);118}119}120}121}122123int OWNED_MONITORS = 1;124int OWNED_SYNCS = 1;125void checkThreadInfo(ThreadInfo info) {126if (!getName().equals(info.getThreadName())) {127throw new RuntimeException("Name: " + info.getThreadName() +128" not matched. Expected: " + getName());129}130131MonitorInfo[] monitors = info.getLockedMonitors();132if (monitors.length != OWNED_MONITORS) {133throw new RuntimeException("Number of locked monitors = " +134monitors.length +135" not matched. Expected: " + OWNED_MONITORS);136}137MonitorInfo m = monitors[0];138StackTraceElement ste = m.getLockedStackFrame();139int depth = m.getLockedStackDepth();140StackTraceElement[] stacktrace = info.getStackTrace();141if (!ste.equals(stacktrace[depth])) {142System.out.println("LockedStackFrame:- " + ste);143System.out.println("StackTrace at " + depth + " :-" +144stacktrace[depth]);145throw new RuntimeException("LockedStackFrame does not match " +146"stack frame in ThreadInfo.getStackTrace");147}148149String className = lock.getClass().getName();150int hcode = System.identityHashCode(lock);151if (!className.equals(m.getClassName()) ||152hcode != m.getIdentityHashCode() ||153!m.getLockedStackFrame().getMethodName().equals("run")) {154System.out.println(info);155throw new RuntimeException("MonitorInfo " + m +156" doesn't match.");157}158159LockInfo[] syncs = info.getLockedSynchronizers();160if (syncs.length != OWNED_SYNCS) {161throw new RuntimeException("Number of locked syncs = " +162syncs.length + " not matched. Expected: " + OWNED_SYNCS);163}164AbstractOwnableSynchronizer s = mutex.getSync();165String lockName = s.getClass().getName();166hcode = System.identityHashCode(s);167if (!lockName.equals(syncs[0].getClassName())) {168throw new RuntimeException("LockInfo : " + syncs[0] +169" class name not matched. Expected: " + lockName);170}171if (hcode != syncs[0].getIdentityHashCode()) {172throw new RuntimeException("LockInfo: " + syncs[0] +173" IdentityHashCode not matched. Expected: " + hcode);174}175LockInfo li = info.getLockInfo();176if (li == null) {177throw new RuntimeException("Expected non-null LockInfo");178}179}180}181static class Mutex implements Lock, java.io.Serializable {182183// Our internal helper class184class Sync extends AbstractQueuedSynchronizer {185// Report whether in locked state186protected boolean isHeldExclusively() {187return getState() == 1;188}189190// Acquire the lock if state is zero191public boolean tryAcquire(int acquires) {192assert acquires == 1; // Otherwise unused193if (compareAndSetState(0, 1)) {194setExclusiveOwnerThread(Thread.currentThread());195return true;196}197return false;198}199200// Release the lock by setting state to zero201protected boolean tryRelease(int releases) {202assert releases == 1; // Otherwise unused203if (getState() == 0) throw new IllegalMonitorStateException();204setExclusiveOwnerThread(null);205setState(0);206return true;207}208209// Provide a Condition210Condition newCondition() { return new ConditionObject(); }211212// Deserialize properly213private void readObject(ObjectInputStream s)214throws IOException, ClassNotFoundException {215s.defaultReadObject();216setState(0); // reset to unlocked state217}218219protected Thread getLockOwner() {220return getExclusiveOwnerThread();221}222}223224// The sync object does all the hard work. We just forward to it.225private final Sync sync = new Sync();226227public void lock() { sync.acquire(1); }228public boolean tryLock() { return sync.tryAcquire(1); }229public void unlock() { sync.release(1); }230public Condition newCondition() { return sync.newCondition(); }231public boolean isLocked() { return sync.isHeldExclusively(); }232public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }233public void lockInterruptibly() throws InterruptedException {234sync.acquireInterruptibly(1);235}236public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {237return sync.tryAcquireNanos(1, unit.toNanos(timeout));238}239240public Thread getLockOwner() { return sync.getLockOwner(); }241242public AbstractOwnableSynchronizer getSync() { return sync; }243}244}245246247