Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/SynchronizerLockingThread.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 SynchronizersLockingThread is used by LockedSynchronizers.26* It will create threads that acquire ReentrantLock and also object27* monitors.28* @author Mandy Chung29*30* @build ThreadDump Utils31*/3233import java.lang.management.*;34import java.util.*;35import java.util.concurrent.locks.ReentrantLock;36import java.util.concurrent.locks.Condition;3738public class SynchronizerLockingThread extends Thread {39static ReentrantLock lock1 = new ReentrantLock();40static ReentrantLock lock2 = new ReentrantLock();41static ReentrantLock lock3 = new ReentrantLock();42static ReentrantLock lock4 = new ReentrantLock();43static Lock lock5 = new Lock("lock5");44static Lock lock6 = new Lock("lock6");45static Lock lock7 = new Lock("lock7");46static ReentrantLock lock8 = new ReentrantLock();4748static SynchronizerLockingThread t1 = new Thread1();49static SynchronizerLockingThread t2 = new Thread2();50static int count = 2;51static void startLockingThreads() {52t1.setDaemon(true);53t2.setDaemon(true);54t1.start();55t2.start();5657// wait until t1 and t2 waits58while (count != 0) {59try {60Thread.sleep(100);61} catch (InterruptedException e) {62throw new RuntimeException(e);63}64}6566Utils.waitForBlockWaitingState(t1);67Utils.waitForBlockWaitingState(t2);68}6970static long[] getThreadIds() {71return new long[] {t1.getId(), t2.getId()};72}7374static void checkLocks(ThreadInfo[] tinfos) throws Exception {75int matches = 0;76for (ThreadInfo info : tinfos) {77if (info.getThreadId() == t1.getId()) {78t1.checkLocks(info);79matches++;80}81if (info.getThreadId() == t2.getId()) {82t2.checkLocks(info);83matches++;84}85}86if (matches != 2) {87throw new RuntimeException("MonitorInfo missing");88}89}9091static class Lock {92String name;93Lock(String name) {94this.name = name;95}96public String toString() {97return name;98}99}100101final String threadName;102Lock waitingLock;103int numOwnedMonitors;104Map<String, Lock[]> ownedMonitors;105Condition waitingSync;106int numOwnedSyncs;107Map<String, ReentrantLock[]> ownedSyncs;108public SynchronizerLockingThread(String name) {109this.threadName = name;110}111112protected void setExpectedResult(Lock waitingLock,113int numOwnedMonitors,114Map<String, Lock[]> ownedMonitors,115Condition waitingSync,116int numOwnedSyncs,117Map<String, ReentrantLock[]> ownedSyncs) {118this.waitingLock = waitingLock;119this.numOwnedMonitors = numOwnedMonitors;120this.ownedMonitors = ownedMonitors;121this.waitingSync = waitingSync;122this.numOwnedSyncs = numOwnedSyncs;123this.ownedSyncs = ownedSyncs;124}125126void checkLocks(ThreadInfo info) throws Exception {127checkThreadInfo(info);128MonitorInfo[] monitors = info.getLockedMonitors();129if (monitors.length != numOwnedMonitors) {130ThreadDump.threadDump();131throw new RuntimeException("Number of locked monitors = " +132monitors.length +133" not matched. Expected: " + numOwnedMonitors);134}135// check if each monitor returned in the list is the expected136// one137for (MonitorInfo m : monitors) {138StackTraceElement ste = m.getLockedStackFrame();139int depth = m.getLockedStackDepth();140checkStackFrame(info, ste, depth);141checkMonitor(m, ste.getMethodName());142}143// check if each expected monitor is included in the returned144// list145for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {146for (Lock l : e.getValue()) {147checkMonitor(e.getKey(), l, monitors);148}149}150151// We can only check if the length matches since we have no152// way to get the AbstractOwnableSynchronizer in ReentrantLock153LockInfo[] syncs = info.getLockedSynchronizers();154if (syncs.length != numOwnedSyncs) {155ThreadDump.threadDump();156throw new RuntimeException("Number of locked syncs = " +157syncs.length +158" not matched. Expected: " + numOwnedSyncs);159}160}161162void checkThreadInfo(ThreadInfo info) throws Exception {163if (!getName().equals(info.getThreadName())) {164throw new RuntimeException("Name: " + info.getThreadName() +165" not matched. Expected: " + getName());166}167LockInfo l = info.getLockInfo();168if ((waitingLock != null || waitingSync != null) && l == null) {169throw new RuntimeException("LockInfo: " + l +170" not matched. Expected: non-null");171}172if (waitingLock == null && waitingSync == null && l != null) {173throw new RuntimeException("LockInfo: " + l +174" not matched. Expected: null");175}176177String waitingLockName;178int hcode;179if (waitingLock != null) {180waitingLockName = waitingLock.getClass().getName();181hcode = System.identityHashCode(waitingLock);182} else {183waitingLockName = waitingSync.getClass().getName();184hcode = System.identityHashCode(waitingSync);185}186if (!waitingLockName.equals(l.getClassName())) {187throw new RuntimeException("LockInfo : " + l +188" class name not matched. Expected: " + waitingLockName);189}190if (hcode != l.getIdentityHashCode()) {191throw new RuntimeException("LockInfo: " + l +192" IdentityHashCode not matched. Expected: " + hcode);193}194195String lockName = info.getLockName();196String[] s = lockName.split("@");197if (!waitingLockName.equals(s[0])) {198throw new RuntimeException("LockName: " + lockName +199" class name not matched. Expected: " + waitingLockName);200}201int i = Integer.parseInt(s[1], 16);202if (hcode != i) {203throw new RuntimeException("LockName: " + lockName +204" IdentityHashCode not matched. Expected: " + hcode);205}206}207208void checkStackFrame(ThreadInfo info, StackTraceElement ste, int depth) {209StackTraceElement[] stacktrace = info.getStackTrace();210if (!ste.equals(stacktrace[depth])) {211System.out.println("LockedStackFrame:- " + ste);212System.out.println("StackTrace at " + depth + " :-" +213stacktrace[depth]);214throw new RuntimeException("LockedStackFrame does not match " +215"stack frame in ThreadInfo.getStackTrace");216}217}218void checkMonitor(MonitorInfo m, String methodName) {219for (Map.Entry<String, Lock[]> e : ownedMonitors.entrySet()) {220if (methodName.equals(e.getKey())) {221for (Lock l : e.getValue()) {222String className = l.getClass().getName();223int hcode = System.identityHashCode(l);224if (className.equals(m.getClassName()) &&225hcode == m.getIdentityHashCode()) {226// monitor matched the expected227return;228}229}230}231}232throw new RuntimeException("Monitor not expected" + m);233}234void checkMonitor(String methodName, Lock l, MonitorInfo[] monitors) {235String className = l.getClass().getName();236int hcode = System.identityHashCode(l);237for (MonitorInfo m : monitors) {238if (className.equals(m.getClassName()) &&239hcode == m.getIdentityHashCode() &&240methodName.equals(m.getLockedStackFrame().getMethodName())) {241return;242}243}244throw new RuntimeException("Monitor not found in the returned list" +245" Method: " + methodName + " Lock: " + l);246247}248249static class Thread1 extends SynchronizerLockingThread {250public Thread1() {251super("t1");252initExpectedResult();253}254public void run() {255A();256}257void A() {258lock1.lock();259try {260lock2.lock();261try {262lock3.lock();263try {264B();265} finally {266lock3.unlock();267}268} finally {269lock2.unlock();270}271} finally {272lock1.unlock();273}274}275void B() {276lock4.lock();277try {278synchronized(lock5) {279C();280}281} finally {282lock4.unlock();283}284}285void C() {286synchronized(lock6) {287D();288}289}290void D() {291synchronized(lock7) {292try {293// signal to about to wait294count--;295lock7.wait();296} catch (InterruptedException e) {297throw new RuntimeException(e);298}299}300}301302Map<String, Lock[]> LOCKED_MONITORS;303Map<String, ReentrantLock[]> LOCKED_SYNCS;304Lock WAITING_LOCK = lock7;305int OWNED_MONITORS = 2;306int OWNED_SYNCS = 4;307void initExpectedResult() {308LOCKED_MONITORS = new HashMap<String, Lock[]>();309LOCKED_MONITORS.put("D", new Lock[0]); // no monitored locked310LOCKED_MONITORS.put("C", new Lock[] {lock6});311LOCKED_MONITORS.put("B", new Lock[] {lock5});312LOCKED_MONITORS.put("A", new Lock[0]);313314LOCKED_SYNCS = new HashMap<String, ReentrantLock[]>();315LOCKED_SYNCS.put("D", new ReentrantLock[0]); // no sync locked316LOCKED_SYNCS.put("C", new ReentrantLock[0]); // no sync locked317LOCKED_SYNCS.put("B", new ReentrantLock[] {lock4});318LOCKED_SYNCS.put("A", new ReentrantLock[] {lock3, lock2, lock1});319this.setExpectedResult(WAITING_LOCK,320OWNED_MONITORS, LOCKED_MONITORS,321null,322OWNED_SYNCS, LOCKED_SYNCS);323}324325}326327static class Thread2 extends SynchronizerLockingThread {328Map<String, Lock[]> LOCKED_MONITORS = new HashMap<String, Lock[]>();329Map<String, ReentrantLock[]> LOCKED_SYNCS = new HashMap<String, ReentrantLock[]>();330Condition c = lock8.newCondition();331Condition WAITING_LOCK = c;332int OWNED_MONITORS = 0;333int OWNED_SYNCS = 0;334public Thread2() {335super("t2");336this.setExpectedResult(null,337OWNED_MONITORS, LOCKED_MONITORS,338WAITING_LOCK,339OWNED_SYNCS, LOCKED_SYNCS);340}341public void run() {342lock8.lock();343try {344synchronized(lock7) {345count--;346}347c.await();348} catch (InterruptedException e) {349throw new RuntimeException(e);350} finally {351lock8.unlock();352}353throw new RuntimeException("should not reach here");354}355}356357}358359360