Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/LockingThread.java
41152 views
/*1* Copyright (c) 2005, 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* @bug 5086470 635824725* @summary LockingThread is used by LockedMonitors test.26* It will create threads that have:27* - a stack frame acquires no monitor28* - a stack frame acquires one or more monitors29* - a stack frame blocks on Object.wait30* and the monitor waiting is not locked.31* @author Mandy Chung32*33* @build Barrier34* @build ThreadDump35*/3637import java.lang.management.*;38import java.util.*;3940public class LockingThread extends Thread {41static Lock lock1 = new Lock("lock1");42static Lock lock2 = new Lock("lock2");43static Lock lock3 = new Lock("lock3");44static Lock lock4 = new Lock("lock4");45static Lock lock5 = new Lock("lock5");46static Lock lock6 = new Lock("lock6");47static Lock lock7 = new Lock("lock7");48static Lock lock8 = new Lock("lock8");4950static LockingThread t1 = new Thread1();51static LockingThread t2 = new Thread2();52static Barrier barr = new Barrier(2);53static int count = 2;54static void startLockingThreads() {55t1.setDaemon(true);56t2.setDaemon(true);57t1.start();58t2.start();5960// wait until t1 waits61while (count != 0) {62try {63Thread.sleep(100);64} catch (InterruptedException e) {65throw new RuntimeException(e);66}67}68Utils.waitForBlockWaitingState(t1);69Utils.waitForBlockWaitingState(t2);70}71static long[] getThreadIds() {72return new long[] {t1.getId(), t2.getId()};73}7475static void checkLockedMonitors(ThreadInfo[] tinfos)76throws Exception {7778int matches = 0;79for (ThreadInfo ti : tinfos) {80if (ti.getThreadId() == t1.getId()) {81t1.checkLockedMonitors(ti);82matches++;83}84if (ti.getThreadId() == t2.getId()) {85t2.checkLockedMonitors(ti);86matches++;87}88}89if (matches != 2) {90throw new RuntimeException("MonitorInfo missing");91}92}9394static class Lock {95String name;96Lock(String name) {97this.name = name;98}99public String toString() {100return name;101}102}103104final String threadName;105Lock waitingLock;106int numOwnedMonitors;107Map<String, Lock[]> ownedMonitors;108public LockingThread(String name) {109this.threadName = name;110}111112protected void setExpectedResult(Lock waitingLock,113int numOwnedMonitors,114Map<String, Lock[]> ownedMonitors) {115this.waitingLock = waitingLock;116this.numOwnedMonitors = numOwnedMonitors;117this.ownedMonitors = ownedMonitors;118}119120void checkLockedMonitors(ThreadInfo info)121throws Exception {122checkThreadInfo(info);123124MonitorInfo[] monitors = info.getLockedMonitors();125if (monitors.length != numOwnedMonitors) {126ThreadDump.threadDump();127throw new RuntimeException("Number of locked monitors = " +128monitors.length +129" not matched. Expected: " + numOwnedMonitors);130}131// check if each monitor returned in the list is the expected132// one133for (MonitorInfo m : monitors) {134StackTraceElement ste = m.getLockedStackFrame();135int depth = m.getLockedStackDepth();136checkStackFrame(info, ste, depth);137checkMonitor(m, ste.getMethodName());138}139// check if each expected monitor is included in the returned140// list141for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {142for (Lock l : e.getValue()) {143checkMonitor(e.getKey(), l, monitors);144}145}146147if (info.getLockedSynchronizers().length != 0) {148ThreadDump.threadDump();149throw new RuntimeException("Number of locked synchronizers = " +150info.getLockedSynchronizers().length +151" not matched. Expected: 0.");152}153}154155void checkThreadInfo(ThreadInfo info) throws Exception {156if (!getName().equals(info.getThreadName())) {157throw new RuntimeException("Name: " + info.getThreadName() +158" not matched. Expected: " + getName());159}160LockInfo l = info.getLockInfo();161if ((waitingLock == null && l != null) ||162(waitingLock != null && l == null)) {163throw new RuntimeException("LockInfo: " + l +164" not matched. Expected: " + waitingLock);165}166167String waitingLockName = waitingLock.getClass().getName();168int hcode = System.identityHashCode(waitingLock);169if (!waitingLockName.equals(l.getClassName())) {170throw new RuntimeException("LockInfo : " + l +171" class name not matched. Expected: " + waitingLockName);172}173if (hcode != l.getIdentityHashCode()) {174throw new RuntimeException("LockInfo: " + l +175" IdentityHashCode not matched. Expected: " + hcode);176}177178String lockName = info.getLockName();179String[] s = lockName.split("@");180if (!waitingLockName.equals(s[0])) {181throw new RuntimeException("LockName: " + lockName +182" class name not matched. Expected: " + waitingLockName);183}184int i = Integer.parseInt(s[1], 16);185if (hcode != i) {186throw new RuntimeException("LockName: " + lockName +187" IdentityHashCode not matched. Expected: " + hcode);188}189}190191void checkStackFrame(ThreadInfo info, StackTraceElement ste, int depth) {192StackTraceElement[] stacktrace = info.getStackTrace();193if (!ste.equals(stacktrace[depth])) {194System.out.println("LockedStackFrame:- " + ste);195System.out.println("StackTrace at " + depth + " :-" +196stacktrace[depth]);197throw new RuntimeException("LockedStackFrame does not match " +198"stack frame in ThreadInfo.getStackTrace");199}200}201void checkMonitor(MonitorInfo m, String methodName) {202for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {203if (methodName.equals(e.getKey())) {204for (Lock l : e.getValue()) {205String className = l.getClass().getName();206int hcode = System.identityHashCode(l);207if (className.equals(m.getClassName()) &&208hcode == m.getIdentityHashCode()) {209// monitor matched the expected210return;211}212}213}214}215throw new RuntimeException("Monitor not expected" + m);216}217void checkMonitor(String methodName, Lock l, MonitorInfo[] monitors) {218String className = l.getClass().getName();219int hcode = System.identityHashCode(l);220for (MonitorInfo m : monitors) {221if (className.equals(m.getClassName()) &&222hcode == m.getIdentityHashCode() &&223methodName.equals(m.getLockedStackFrame().getMethodName())) {224return;225}226}227throw new RuntimeException("Monitor not found in the returned list" +228" Method: " + methodName + " Lock: " + l);229230}231232static class Thread1 extends LockingThread {233public Thread1() {234super("t1");235initExpectedResult();236}237public void run() {238A();239}240void A() {241synchronized(lock1) {242synchronized(lock2) {243synchronized(lock3) {244B();245}246}247}248}249void B() {250synchronized(lock4) {251synchronized(lock5) {252C();253}254}255}256void C() {257synchronized(lock6) {258D();259}260}261void D() {262synchronized(lock7) {263try {264// signal to about to wait265count--;266lock7.wait();267} catch (InterruptedException e) {268throw new RuntimeException(e);269}270}271}272273Map<String, Lock[]> LOCKED_MONITORS;274Lock WAITING_LOCK = lock7;275int OWNED_MONITORS = 6;276void initExpectedResult() {277LOCKED_MONITORS = new HashMap<String, Lock[]>();278LOCKED_MONITORS.put("D", new Lock[0]); // no monitored locked279LOCKED_MONITORS.put("C", new Lock[] {lock6});280LOCKED_MONITORS.put("B", new Lock[] {lock5, lock4});281LOCKED_MONITORS.put("A", new Lock[] {lock3, lock2, lock1});282this.setExpectedResult(WAITING_LOCK, OWNED_MONITORS, LOCKED_MONITORS);283}284285}286287static class Thread2 extends LockingThread {288Map<String, Lock[]> LOCKED_MONITORS = new HashMap<String, Lock[]>();289Lock WAITING_LOCK = lock8;290int OWNED_MONITORS = 0;291public Thread2() {292super("t2");293this.setExpectedResult(WAITING_LOCK, OWNED_MONITORS, LOCKED_MONITORS);294}295public void run() {296synchronized(lock8) {297try {298synchronized(lock7) {299count--;300}301lock8.wait();302} catch (InterruptedException e) {303throw new RuntimeException(e);304}305}306}307}308309}310311312