8324066: "clhsdb jstack" should not by default scan for j.u.c locks because it can be very slow
Reviewed-by: kevinw, amenkov
This commit is contained in:
parent
6b09a79d64
commit
192349eee4
@ -53,7 +53,7 @@ Available commands:
|
|||||||
intConstant [ name [ value ] ] <font color="red">print out hotspot integer constant(s)</font>
|
intConstant [ name [ value ] ] <font color="red">print out hotspot integer constant(s)</font>
|
||||||
jdis address <font color="red">show bytecode disassembly of a given Method*</font>
|
jdis address <font color="red">show bytecode disassembly of a given Method*</font>
|
||||||
jhisto <font color="red">show Java heap histogram</font>
|
jhisto <font color="red">show Java heap histogram</font>
|
||||||
jstack [-v] <font color="red">show Java stack trace of all Java threads. -v is verbose mode</font>
|
jstack [-v] [-l] <font color="red">show Java stack trace of all Java threads. -v is verbose mode. -l includes info on owned java.util.concurrent locks.</font>
|
||||||
livenmethods <font color="red">show all live nmethods</font>
|
livenmethods <font color="red">show all live nmethods</font>
|
||||||
longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
|
longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
|
||||||
mem [ -v ] { address[/count] | address,address } <font color="red">show contents of memory range. -v adds "findpc" info for addresses</font>
|
mem [ -v ] { address[/count] | address,address } <font color="red">show contents of memory range. -v adds "findpc" info for addresses</font>
|
||||||
@ -62,7 +62,7 @@ Available commands:
|
|||||||
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread <address></font>
|
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread <address></font>
|
||||||
printmdo -a | expression <font color="red">print method data oop</font>
|
printmdo -a | expression <font color="red">print method data oop</font>
|
||||||
printstatics [ type ] <font color="red">print static fields of given HotSpot type (or all types if none specified)</font>
|
printstatics [ type ] <font color="red">print static fields of given HotSpot type (or all types if none specified)</font>
|
||||||
pstack [-v] <font color="red">show mixed mode stack trace for all Java, non-Java threads. -v is verbose mode</font>
|
pstack [-v] [-l] <font color="red">show mixed mode stack trace for all Java, non-Java threads. -v is verbose mode. -l includes info on owned java.util.concurrent locks.</font>
|
||||||
quit <font color="red">quit CLHSDB tool</font>
|
quit <font color="red">quit CLHSDB tool</font>
|
||||||
reattach <font color="red">detach and re-attach SA to current target</font>
|
reattach <font color="red">detach and re-attach SA to current target</font>
|
||||||
revptrs <font color="red">find liveness of oops</font>
|
revptrs <font color="red">find liveness of oops</font>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1143,13 +1143,22 @@ public class CommandProcessor {
|
|||||||
histo.run(out, err);
|
histo.run(out, err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Command("jstack", "jstack [-v]", false) {
|
new Command("jstack", "jstack [-v] [-l]", false) {
|
||||||
public void doit(Tokens t) {
|
public void doit(Tokens t) {
|
||||||
boolean verbose = false;
|
boolean verbose = false;
|
||||||
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
|
boolean concurrentLocks = false;
|
||||||
verbose = true;
|
while (t.countTokens() > 0) {
|
||||||
|
String arg = t.nextToken();
|
||||||
|
if (arg.equals("-v")) {
|
||||||
|
verbose = true;
|
||||||
|
} else if (arg.equals("-l")) {
|
||||||
|
concurrentLocks = true;
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StackTrace jstack = new StackTrace(verbose, true);
|
StackTrace jstack = new StackTrace(verbose, concurrentLocks);
|
||||||
jstack.run(out);
|
jstack.run(out);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1201,13 +1210,22 @@ public class CommandProcessor {
|
|||||||
pmap.run(out, debugger.getAgent().getDebugger());
|
pmap.run(out, debugger.getAgent().getDebugger());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Command("pstack", "pstack [-v]", false) {
|
new Command("pstack", "pstack [-v] [-l]", false) {
|
||||||
public void doit(Tokens t) {
|
public void doit(Tokens t) {
|
||||||
boolean verbose = false;
|
boolean verbose = false;
|
||||||
if (t.countTokens() > 0 && t.nextToken().equals("-v")) {
|
boolean concurrentLocks = false;
|
||||||
verbose = true;
|
while (t.countTokens() > 0) {
|
||||||
|
String arg = t.nextToken();
|
||||||
|
if (arg.equals("-v")) {
|
||||||
|
verbose = true;
|
||||||
|
} else if (arg.equals("-l")) {
|
||||||
|
concurrentLocks = true;
|
||||||
|
} else {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PStack pstack = new PStack(verbose, true, debugger.getAgent());
|
PStack pstack = new PStack(verbose, concurrentLocks, debugger.getAgent());
|
||||||
pstack.run(out, debugger.getAgent().getDebugger());
|
pstack.run(out, debugger.getAgent().getDebugger());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,12 +31,14 @@ import sun.jvm.hotspot.oops.*;
|
|||||||
|
|
||||||
public class ConcurrentLocksPrinter {
|
public class ConcurrentLocksPrinter {
|
||||||
private final Map<JavaThread, List<Oop>> locksMap = new HashMap<>();
|
private final Map<JavaThread, List<Oop>> locksMap = new HashMap<>();
|
||||||
|
private PrintStream tty;
|
||||||
|
|
||||||
public ConcurrentLocksPrinter() {
|
public ConcurrentLocksPrinter(PrintStream tty) {
|
||||||
|
this.tty = tty;
|
||||||
fillLocks();
|
fillLocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void print(JavaThread jthread, PrintStream tty) {
|
public void print(JavaThread jthread) {
|
||||||
List<Oop> locks = locksMap.get(jthread);
|
List<Oop> locks = locksMap.get(jthread);
|
||||||
tty.println("Locked ownable synchronizers:");
|
tty.println("Locked ownable synchronizers:");
|
||||||
if (locks == null || locks.isEmpty()) {
|
if (locks == null || locks.isEmpty()) {
|
||||||
@ -66,6 +68,7 @@ public class ConcurrentLocksPrinter {
|
|||||||
ObjectHeap heap = vm.getObjectHeap();
|
ObjectHeap heap = vm.getObjectHeap();
|
||||||
// may be not loaded at all
|
// may be not loaded at all
|
||||||
if (absOwnSyncKlass != null) {
|
if (absOwnSyncKlass != null) {
|
||||||
|
tty.println("Finding concurrent locks. This might take a while...");
|
||||||
heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
|
heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
|
||||||
public boolean doObj(Oop oop) {
|
public boolean doObj(Oop oop) {
|
||||||
JavaThread thread = getOwnerThread(oop);
|
JavaThread thread = getOwnerThread(oop);
|
||||||
@ -77,6 +80,7 @@ public class ConcurrentLocksPrinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}, absOwnSyncKlass, true);
|
}, absOwnSyncKlass, true);
|
||||||
|
tty.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class PStack extends Tool {
|
|||||||
// compute and cache java Vframes.
|
// compute and cache java Vframes.
|
||||||
initJFrameCache();
|
initJFrameCache();
|
||||||
if (concurrentLocks) {
|
if (concurrentLocks) {
|
||||||
concLocksPrinter = new ConcurrentLocksPrinter();
|
concLocksPrinter = new ConcurrentLocksPrinter(out);
|
||||||
}
|
}
|
||||||
// print Java level deadlocks
|
// print Java level deadlocks
|
||||||
try {
|
try {
|
||||||
@ -192,7 +192,7 @@ public class PStack extends Tool {
|
|||||||
if (concurrentLocks) {
|
if (concurrentLocks) {
|
||||||
JavaThread jthread = proxyToThread.get(th);
|
JavaThread jthread = proxyToThread.get(th);
|
||||||
if (jthread != null) {
|
if (jthread != null) {
|
||||||
concLocksPrinter.print(jthread, out);
|
concLocksPrinter.print(jthread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for threads
|
} // for threads
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -68,7 +68,7 @@ public class StackTrace extends Tool {
|
|||||||
try {
|
try {
|
||||||
ConcurrentLocksPrinter concLocksPrinter = null;
|
ConcurrentLocksPrinter concLocksPrinter = null;
|
||||||
if (concurrentLocks) {
|
if (concurrentLocks) {
|
||||||
concLocksPrinter = new ConcurrentLocksPrinter();
|
concLocksPrinter = new ConcurrentLocksPrinter(tty);
|
||||||
}
|
}
|
||||||
Threads threads = VM.getVM().getThreads();
|
Threads threads = VM.getVM().getThreads();
|
||||||
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
|
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
|
||||||
@ -123,9 +123,9 @@ public class StackTrace extends Tool {
|
|||||||
}
|
}
|
||||||
tty.println();
|
tty.println();
|
||||||
if (concurrentLocks) {
|
if (concurrentLocks) {
|
||||||
concLocksPrinter.print(cur, tty);
|
concLocksPrinter.print(cur);
|
||||||
|
tty.println();
|
||||||
}
|
}
|
||||||
tty.println();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -51,6 +51,7 @@ serviceability/sa/ClhsdbJdis.java 8307393 generic-
|
|||||||
serviceability/sa/ClhsdbJhisto.java 8307393 generic-all
|
serviceability/sa/ClhsdbJhisto.java 8307393 generic-all
|
||||||
serviceability/sa/ClhsdbJstack.java#id0 8307393 generic-all
|
serviceability/sa/ClhsdbJstack.java#id0 8307393 generic-all
|
||||||
serviceability/sa/ClhsdbJstack.java#id1 8307393 generic-all
|
serviceability/sa/ClhsdbJstack.java#id1 8307393 generic-all
|
||||||
|
serviceability/sa/ClhsdbJstackWithConcurrentLock.java 8307393 generic-all
|
||||||
serviceability/sa/ClhsdbJstackXcompStress.java 8307393 generic-all
|
serviceability/sa/ClhsdbJstackXcompStress.java 8307393 generic-all
|
||||||
serviceability/sa/ClhsdbLauncher.java 8307393 generic-all
|
serviceability/sa/ClhsdbLauncher.java 8307393 generic-all
|
||||||
serviceability/sa/ClhsdbLongConstant.java 8307393 generic-all
|
serviceability/sa/ClhsdbLongConstant.java 8307393 generic-all
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,6 +30,7 @@
|
|||||||
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8276539 generic-all
|
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8276539 generic-all
|
||||||
serviceability/sa/CDSJMapClstats.java 8276539 generic-all
|
serviceability/sa/CDSJMapClstats.java 8276539 generic-all
|
||||||
serviceability/sa/ClhsdbJhisto.java 8276539 generic-all
|
serviceability/sa/ClhsdbJhisto.java 8276539 generic-all
|
||||||
|
serviceability/sa/ClhsdbJstackWithConcurrentLock.java 8276539 generic-all
|
||||||
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java 8276539 generic-all
|
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java 8276539 generic-all
|
||||||
|
|
||||||
serviceability/sa/ClhsdbFindPC.java#xcomp-core 8284045 generic-all
|
serviceability/sa/ClhsdbFindPC.java#xcomp-core 8284045 generic-all
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8324066
|
||||||
|
* @summary Test the clhsdb 'jstack -l' command for printing concurrent lock information
|
||||||
|
* @requires vm.hasSA
|
||||||
|
* @library /test/lib
|
||||||
|
* @run main/othervm ClhsdbJstackWithConcurrentLock
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import jdk.test.lib.apps.LingeredApp;
|
||||||
|
import jtreg.SkippedException;
|
||||||
|
|
||||||
|
public class ClhsdbJstackWithConcurrentLock {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("Starting the ClhsdbJstackWithConcurrentLock test");
|
||||||
|
|
||||||
|
LingeredApp theApp = null;
|
||||||
|
try {
|
||||||
|
ClhsdbLauncher test = new ClhsdbLauncher();
|
||||||
|
|
||||||
|
theApp = new LingeredAppWithConcurrentLock();
|
||||||
|
// Use a small heap so the scan is quick.
|
||||||
|
LingeredApp.startApp(theApp, "-Xmx4m");
|
||||||
|
System.out.println("Started LingeredApp with pid " + theApp.getPid());
|
||||||
|
|
||||||
|
// Run the 'jstack -l' command to get the stack and have java.util.concurrent
|
||||||
|
// lock information included.
|
||||||
|
List<String> cmds = List.of("jstack -l");
|
||||||
|
String jstackOutput = test.run(theApp.getPid(), cmds, null, null);
|
||||||
|
|
||||||
|
// We are looking for:
|
||||||
|
// Locked ownable synchronizers:
|
||||||
|
// - <0x00000000ffc2ed70>, (a java/util/concurrent/locks/ReentrantLock$NonfairSync)
|
||||||
|
// We want to fetch the address from this line.
|
||||||
|
String key = ", (a java/util/concurrent/locks/ReentrantLock$NonfairSync)";
|
||||||
|
String[] lines = jstackOutput.split("\\R");
|
||||||
|
String addressString = null;
|
||||||
|
for (String line : lines) {
|
||||||
|
if (line.contains(key)) {
|
||||||
|
String[] words = line.split("[, ]");
|
||||||
|
for (String word : words) {
|
||||||
|
word = word.replace("<", "").replace(">", "");
|
||||||
|
if (word.startsWith("0x")) {
|
||||||
|
addressString = word;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addressString != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (addressString == null) {
|
||||||
|
throw new RuntimeException("Token '" + key + "' not found in jstack output");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are looking for the following java frame:
|
||||||
|
// - jdk.internal.misc.Unsafe.park(boolean, long)...
|
||||||
|
// - parking to wait for <0x00000000ffc2ed70> (a java/util/concurrent/locks/ReentrantLock$NonfairSync)
|
||||||
|
// Note the address matches the one we found above.
|
||||||
|
key = "- parking to wait for <" + addressString +
|
||||||
|
"> (a java/util/concurrent/locks/ReentrantLock$NonfairSync)";
|
||||||
|
boolean found = false;
|
||||||
|
for (String line : lines) {
|
||||||
|
if (line.contains(key)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
throw new RuntimeException("Token '" + key + "' not found in jstack output");
|
||||||
|
}
|
||||||
|
} catch (SkippedException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException("Test ERROR " + ex, ex);
|
||||||
|
} finally {
|
||||||
|
LingeredApp.stopApp(theApp);
|
||||||
|
System.out.println("OUTPUT: " + theApp.getOutput());
|
||||||
|
}
|
||||||
|
System.out.println("Test PASSED");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.apps.LingeredApp;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
|
||||||
|
public class LingeredAppWithConcurrentLock extends LingeredApp {
|
||||||
|
|
||||||
|
private static final Lock lock = new ReentrantLock();
|
||||||
|
|
||||||
|
public static void lockMethod(Lock lock) {
|
||||||
|
lock.lock();
|
||||||
|
synchronized (lock) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(300000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
Thread classLock1 = new Thread(() -> lockMethod(lock));
|
||||||
|
Thread classLock2 = new Thread(() -> lockMethod(lock));
|
||||||
|
Thread classLock3 = new Thread(() -> lockMethod(lock));
|
||||||
|
|
||||||
|
classLock1.start();
|
||||||
|
classLock2.start();
|
||||||
|
classLock3.start();
|
||||||
|
|
||||||
|
// Wait until all threads have reached their blocked or timed wait state
|
||||||
|
while ((classLock1.getState() != Thread.State.WAITING &&
|
||||||
|
classLock1.getState() != Thread.State.TIMED_WAITING) ||
|
||||||
|
(classLock2.getState() != Thread.State.WAITING &&
|
||||||
|
classLock2.getState() != Thread.State.TIMED_WAITING) ||
|
||||||
|
(classLock3.getState() != Thread.State.WAITING &&
|
||||||
|
classLock3.getState() != Thread.State.TIMED_WAITING)) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("classLock1 state: " + classLock1.getState());
|
||||||
|
System.out.println("classLock2 state: " + classLock2.getState());
|
||||||
|
System.out.println("classLock3 state: " + classLock3.getState());
|
||||||
|
|
||||||
|
LingeredApp.main(args);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -79,7 +79,7 @@ import jdk.test.lib.util.CoreUtils;
|
|||||||
*
|
*
|
||||||
* After app termination (stopApp/waitAppTermination) its output is available
|
* After app termination (stopApp/waitAppTermination) its output is available
|
||||||
*
|
*
|
||||||
* output = a.getAppOutput();
|
* output = a.getOutput();
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LingeredApp {
|
public class LingeredApp {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user