Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java
41152 views
/*1* Copyright (c) 2003, 2020, 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 4967283 5080203 802220826* @summary Basic unit test of thread states returned by27* ThreadMXBean.getThreadInfo.getThreadState().28* It also tests lock information returned by ThreadInfo.29* @author Mandy Chung30*31* @library ../../Thread32* @library /test/lib33*34* @build ThreadMXBeanStateTest ThreadStateController35* @run main ThreadMXBeanStateTest36*/3738import jdk.test.lib.Utils;3940import java.lang.management.ManagementFactory;41import java.lang.management.ThreadMXBean;42import java.lang.management.ThreadInfo;43import static java.lang.Thread.State.*;4445public class ThreadMXBeanStateTest {46private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();4748static class Lock {49private final String name;50Lock(String name) {51this.name = name;52}53@Override54public String toString() {55return name;56}57}5859private static final Lock globalLock = new Lock("my lock");6061public static void main(String[] argv) throws Exception {62// Force thread state initialization now before the test63// verification begins.64Thread.currentThread().getState();65ThreadStateController thread = new ThreadStateController("StateChanger", globalLock);66thread.setDaemon(true);67try {68// before myThread starts69thread.checkThreadState(NEW);7071thread.start();72thread.transitionTo(RUNNABLE);73thread.checkThreadState(RUNNABLE);74checkLockInfo(thread, RUNNABLE, null, null);7576thread.suspend();77ThreadStateController.pause(10);78thread.checkThreadState(RUNNABLE);79checkSuspendedThreadState(thread, RUNNABLE);80thread.resume();8182synchronized (globalLock) {83thread.transitionTo(BLOCKED);84thread.checkThreadState(BLOCKED);85checkLockInfo(thread, BLOCKED,86globalLock, Thread.currentThread());87}8889thread.transitionTo(WAITING);90thread.checkThreadState(WAITING);91checkLockInfo(thread, Thread.State.WAITING,92globalLock, null);9394thread.transitionTo(TIMED_WAITING);95thread.checkThreadState(TIMED_WAITING);96checkLockInfo(thread, TIMED_WAITING,97globalLock, null);9899100thread.transitionToPark(true /* timed park */);101thread.checkThreadState(TIMED_WAITING);102checkLockInfo(thread, TIMED_WAITING, null, null);103104thread.transitionToPark(false /* indefinite park */);105thread.checkThreadState(WAITING);106checkLockInfo(thread, WAITING, null, null);107108thread.transitionToSleep();109thread.checkThreadState(TIMED_WAITING);110checkLockInfo(thread, TIMED_WAITING, null, null);111112thread.transitionTo(TERMINATED);113thread.checkThreadState(TERMINATED);114} finally {115try {116System.out.println(thread.getLog(Utils.adjustTimeout(60_000)));117} catch (InterruptedException e) {118e.printStackTrace();119System.out.println("TEST FAILED: Unexpected exception.");120throw new RuntimeException(e);121}122}123System.out.println("Test passed.");124}125126private static void checkSuspendedThreadState(ThreadStateController t, Thread.State state) {127ThreadInfo info = getThreadInfo(t, state);128if (info == null) {129throw new RuntimeException(t.getName() +130" expected to have ThreadInfo " +131" but got null.");132}133134if (info.getThreadState() != state) {135throw new RuntimeException(t.getName() + " expected to be in " +136state + " state but got " + info.getThreadState());137}138139if (!info.isSuspended()) {140throw new RuntimeException(t.getName() + " expected to be suspended " +141" but isSuspended() returns " + info.isSuspended());142}143}144145private static String getLockName(Object lock) {146if (lock == null) return null;147148return lock.getClass().getName() + '@' +149Integer.toHexString(System.identityHashCode(lock));150}151152// maximum number of retries when checking for thread state.153private static final int MAX_RETRY = 500;154private static ThreadInfo getThreadInfo(ThreadStateController t, Thread.State expected) {155// wait for the thread to transition to the expected state.156// There is a small window between the thread checking the state157// and the thread actual entering that state.158int retryCount=0;159ThreadInfo info = tm.getThreadInfo(t.getId());160while (info.getThreadState() != expected && retryCount < MAX_RETRY) {161ThreadStateController.pause(10);162retryCount++;163info = tm.getThreadInfo(t.getId());164}165return info;166}167168private static void checkLockInfo(ThreadStateController t, Thread.State state,169Object lock, Thread owner) {170ThreadInfo info = getThreadInfo(t, state);171if (info == null) {172throw new RuntimeException(t.getName() +173" expected to have ThreadInfo " +174" but got null.");175}176177if (info.getThreadState() != state) {178throw new RuntimeException(t.getName() + " expected to be in " +179state + " state but got " + info.getThreadState());180}181182if (lock == null && info.getLockName() != null) {183throw new RuntimeException(t.getName() +184" expected not to be blocked on any lock" +185" but got " + info.getLockName());186}187String expectedLockName = getLockName(lock);188if (lock != null && info.getLockName() == null) {189throw new RuntimeException(t.getName() +190" expected to be blocked on lock [" + expectedLockName +191"] but got null.");192}193194if (lock != null && !expectedLockName.equals(info.getLockName())) {195throw new RuntimeException(t.getName() +196" expected to be blocked on lock [" + expectedLockName +197"] but got [" + info.getLockName() + "].");198}199200if (owner == null && info.getLockOwnerName() != null) {201throw new RuntimeException("Lock owner is expected " +202" to be null but got " + info.getLockOwnerName());203}204205if (owner != null && info.getLockOwnerName() == null) {206throw new RuntimeException("Lock owner is expected to be " +207owner.getName() +208" but got null.");209}210if (owner != null && !info.getLockOwnerName().equals(owner.getName())) {211throw new RuntimeException("Lock owner is expected to be " +212owner.getName() +213" but got " + owner.getName());214}215if (owner == null && info.getLockOwnerId() != -1) {216throw new RuntimeException("Lock owner is expected " +217" to be -1 but got " + info.getLockOwnerId());218}219220if (owner != null && info.getLockOwnerId() <= 0) {221throw new RuntimeException("Lock owner is expected to be " +222owner.getName() + "(id = " + owner.getId() +223") but got " + info.getLockOwnerId());224}225if (owner != null && info.getLockOwnerId() != owner.getId()) {226throw new RuntimeException("Lock owner is expected to be " +227owner.getName() + "(id = " + owner.getId() +228") but got " + info.getLockOwnerId());229}230if (info.isSuspended()) {231throw new RuntimeException(t.getName() +232" isSuspended() returns " + info.isSuspended());233}234}235}236237238