jdk/test/java/lang/management/ThreadMXBean/MonitorDeadlock.java
author mchung
Tue, 26 May 2009 18:07:14 -0700
changeset 2933 08ea3ecb912c
parent 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java Summary: Retry a few times to check thread status before reporting failure Reviewed-by: swamyv
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * @summary MonitorDeadlock creates threads that are deadlocked on
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 *          object monitors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * @author  Mandy Chung
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * @build Barrier
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.lang.management.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
public class MonitorDeadlock {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
    private final int EXPECTED_THREADS = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
    private Barrier go = new Barrier(1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    private Barrier barr = new Barrier(EXPECTED_THREADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    private Object a = new Object();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    private Object b = new Object();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    private Object c = new Object();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    private Thread[] dThreads = new Thread[EXPECTED_THREADS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    public MonitorDeadlock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
        dThreads[0] = new DeadlockingThread("MThread-1", a, b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
        dThreads[1] = new DeadlockingThread("MThread-2", b, c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
        dThreads[2] = new DeadlockingThread("MThread-3", c, a);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
        // make them daemon threads so that the test will exit
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        for (int i = 0; i < EXPECTED_THREADS; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
            dThreads[i].setDaemon(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
            dThreads[i].start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    void goDeadlock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        // Wait until all threads have started
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        barr.await();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        // reset for later signals
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        barr.set(EXPECTED_THREADS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
        while (go.getWaiterCount() != EXPECTED_THREADS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
            synchronized(this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
                    wait(100);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
                } catch (InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
                    // ignore
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        // sleep a little so that all threads are blocked before notified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            Thread.sleep(100);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        } catch (InterruptedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
            // ignore
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        go.signal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    void waitUntilDeadlock() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        barr.await();
2933
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    86
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    87
        for (int i=0; i < 100; i++) {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    88
            // sleep a little while to wait until threads are blocked.
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    89
            try {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    90
                Thread.sleep(100);
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    91
            } catch (InterruptedException e) {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    92
                // ignore
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    93
            }
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    94
            boolean retry = false;
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    95
            for (Thread t: dThreads) {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    96
                if (t.getState() == Thread.State.RUNNABLE) {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    97
                    retry = true;
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    98
                    break;
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
    99
                }
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
   100
            }
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
   101
            if (!retry) {
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
   102
                break;
08ea3ecb912c 6512493: TEST_BUG: unexpected LockInfo failure in LockedSynchronizers.java
mchung
parents: 2
diff changeset
   103
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    private class DeadlockingThread extends Thread {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        private final Object lock1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        private final Object lock2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        DeadlockingThread(String name, Object lock1, Object lock2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            super(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
            this.lock1 = lock1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
            this.lock2 = lock2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            f();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        private void f() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            synchronized (lock1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                barr.signal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                go.await();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                g();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        private void g() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            barr.signal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            synchronized (lock2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                throw new RuntimeException("should not reach here.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    void checkResult(long[] threads) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        if (threads.length != EXPECTED_THREADS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
            throw new RuntimeException("Expected to have " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                EXPECTED_THREADS + " to be in the deadlock list");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        boolean[] found = new boolean[EXPECTED_THREADS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        for (int i = 0; i < threads.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            for (int j = 0; j < dThreads.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                if (dThreads[j].getId() == threads[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                    found[j] = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        boolean ok = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        for (int j = 0; j < found.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            ok = ok && found[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (!ok) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            System.out.print("Returned result is [");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            for (int j = 0; j < threads.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                System.out.print(threads[j] + " ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            System.out.println("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            System.out.print("Expected result is [");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            for (int j = 0; j < threads.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                System.out.print(dThreads[j] + " ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            System.out.println("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            throw new RuntimeException("Unexpected result returned " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                " by findMonitorDeadlockedThreads method.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
}