Path: blob/master/test/jdk/java/lang/management/ThreadMXBean/SynchronizerDeadlock.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* @summary SynchronizerDeadlock creates threads that are deadlocked25* waiting for JSR-166 synchronizers.26* @author Mandy Chung27* @build Barrier28*/2930import java.lang.management.*;31import java.util.*;32import java.util.concurrent.locks.*;3334public class SynchronizerDeadlock {3536private Lock a = new ReentrantLock();37private Lock b = new ReentrantLock();38private Lock c = new ReentrantLock();39private final int EXPECTED_THREADS = 3;40private Thread[] dThreads = new Thread[EXPECTED_THREADS];41private Barrier go = new Barrier(1);42private Barrier barr = new Barrier(EXPECTED_THREADS);4344public SynchronizerDeadlock() {45dThreads[0] = new DeadlockingThread("Deadlock-Thread-1", a, b);46dThreads[1] = new DeadlockingThread("Deadlock-Thread-2", b, c);47dThreads[2] = new DeadlockingThread("Deadlock-Thread-3", c, a);4849// make them daemon threads so that the test will exit50for (int i = 0; i < EXPECTED_THREADS; i++) {51dThreads[i].setDaemon(true);52dThreads[i].start();53}54}5556void goDeadlock() {57// Wait until all threads have started58barr.await();5960// reset for later signals61barr.set(EXPECTED_THREADS);6263while (go.getWaiterCount() != EXPECTED_THREADS) {64synchronized(this) {65try {66wait(100);67} catch (InterruptedException e) {68// ignore69}70}71}7273// sleep a little so that all threads are blocked before notified.74try {75Thread.sleep(100);76} catch (InterruptedException e) {77// ignore78}79go.signal();8081}8283void waitUntilDeadlock() {84barr.await();8586for (int i=0; i < 100; i++) {87// sleep a little while to wait until threads are blocked.88try {89Thread.sleep(100);90} catch (InterruptedException e) {91// ignore92}93boolean retry = false;94for (Thread t: dThreads) {95if (t.getState() == Thread.State.RUNNABLE) {96retry = true;97break;98}99}100if (!retry) {101break;102}103}104}105106private class DeadlockingThread extends Thread {107private final Lock lock1;108private final Lock lock2;109110DeadlockingThread(String name, Lock lock1, Lock lock2) {111super(name);112this.lock1 = lock1;113this.lock2 = lock2;114}115public void run() {116f();117}118private void f() {119lock1.lock();120try {121barr.signal();122go.await();123g();124} finally {125lock1.unlock();126}127}128private void g() {129barr.signal();130lock2.lock();131throw new RuntimeException("should not reach here.");132}133}134135void checkResult(long[] threads) {136if (threads.length != EXPECTED_THREADS) {137ThreadDump.threadDump();138throw new RuntimeException("Expected to have " +139EXPECTED_THREADS + " to be in the deadlock list");140}141boolean[] found = new boolean[EXPECTED_THREADS];142for (int i = 0; i < threads.length; i++) {143for (int j = 0; j < dThreads.length; j++) {144if (dThreads[j].getId() == threads[i]) {145found[j] = true;146}147}148}149boolean ok = true;150for (int j = 0; j < found.length; j++) {151ok = ok && found[j];152}153154if (!ok) {155System.out.print("Returned result is [");156for (int j = 0; j < threads.length; j++) {157System.out.print(threads[j] + " ");158}159System.out.println("]");160161System.out.print("Expected result is [");162for (int j = 0; j < threads.length; j++) {163System.out.print(dThreads[j] + " ");164}165System.out.println("]");166throw new RuntimeException("Unexpected result returned " +167" by findMonitorDeadlockedThreads method.");168}169}170}171172173