jdk/test/javax/management/standardmbean/DeadlockTest.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/standardmbean/DeadlockTest.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6331746
+ * @summary Deadlock on synchronization problem
+ * @author Shanliang JIANG
+ * @run main DeadlockTest
+ */
+
+import javax.management.*;
+import javax.management.timer.*;
+
+public class DeadlockTest extends StandardMBean {
+    public <T> DeadlockTest(T implementation, Class<T> mbeanInterface)
+    throws NotCompliantMBeanException {
+        super(implementation, mbeanInterface);
+    }
+
+    public MBeanInfo getCachedMBeanInfo() {
+        return super.getCachedMBeanInfo();
+    }
+
+    public void cacheMBeanInfo(MBeanInfo mi) {
+        super.cacheMBeanInfo(mi);
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("main: No deadlock please.");
+
+        System.out.println("main: Create a BadBay to hold the lock forever.");
+        DeadlockTest dt = new DeadlockTest(new Timer(), TimerMBean.class);
+
+        BadBoy bb = new BadBoy(dt);
+        bb.start();
+
+        final long timeout = 2000;
+        long stopTime = System.currentTimeMillis() + timeout;
+        long timeToWait = timeout;
+        synchronized(bb) {
+            while(!bb.gotLock || timeToWait > 0) {
+                bb.wait(timeToWait);
+
+                timeToWait = stopTime - System.currentTimeMillis();
+            }
+        }
+
+        if (!bb.gotLock) {
+            throw new RuntimeException("Failed to get lock, impossible!");
+        }
+
+        System.out.println("main: The BadBay is holding the lock forever.");
+
+        System.out.println("main: Create a WorkingBoy to see blocking ...");
+        WorkingBoy wb = new WorkingBoy(dt);
+
+        stopTime = System.currentTimeMillis() + timeout;
+        timeToWait = timeout;
+
+        synchronized(wb) {
+            wb.start();
+
+            while(!wb.done || timeToWait > 0) {
+                wb.wait(timeToWait);
+
+                timeToWait = stopTime - System.currentTimeMillis();
+            }
+        }
+
+        if (!wb.done) {
+            throw new RuntimeException("It is blocked!");
+        }
+
+        System.out.println("main: OK, bye bye.");
+    }
+
+    private static class BadBoy extends Thread {
+        public BadBoy(Object o) {
+            setDaemon(true);
+
+            this.o = o;
+        }
+
+        public void run() {
+            System.out.println("BadBoy-run: keep synchronization lock forever!");
+
+            synchronized(o) {
+                synchronized(this) {
+                    gotLock = true;
+
+                    this.notify();
+                }
+
+                try {
+                    Thread.sleep(10000000);
+                } catch (Exception e) {
+                    // OK
+                }
+            }
+        }
+
+        final Object o;
+        public boolean gotLock;
+    }
+
+    private static class WorkingBoy extends Thread {
+        public WorkingBoy(DeadlockTest sm) {
+            setDaemon(true);
+
+            this.sm = sm;
+        }
+
+        public void run() {
+            try {
+                System.out.println("WorkingBoy-run: calling StandardMBean methods ...");
+
+                System.out.println("WorkingBoy-run: calling setImplementation ...");
+                sm.setImplementation(new Timer());
+
+                System.out.println("WorkingBoy-run: calling getImplementation ...");
+                sm.getImplementation();
+
+                System.out.println("WorkingBoy-run: calling getMBeanInterface ...");
+                sm.getMBeanInterface();
+
+                System.out.println("WorkingBoy-run: calling getImplementationClass ...");
+                sm.getImplementationClass();
+
+                System.out.println("WorkingBoy-run: calling cacheMBeanInfo ...");
+                sm.cacheMBeanInfo(null);
+
+                System.out.println("WorkingBoy-run: calling getCachedMBeanInfo ...");
+                sm.getCachedMBeanInfo();
+
+                System.out.println("WorkingBoy-run: All done!");
+
+                synchronized(this) {
+                    done = true;
+
+                    this.notifyAll();
+                }
+            } catch (NotCompliantMBeanException ne) {
+                // Impossible?
+                throw new RuntimeException(ne);
+            }
+        }
+
+        final DeadlockTest sm;
+        public boolean done;
+    }
+}