jdk/test/java/lang/management/ThreadMXBean/Locks.java
changeset 28101 acc6f4bcb37e
parent 23337 d4a11c730d92
child 30376 2ccf2cf7ea48
equal deleted inserted replaced
28100:d3f16ee13562 28101:acc6f4bcb37e
    27  * @summary Basic unit test of ThreadInfo.getLockName()
    27  * @summary Basic unit test of ThreadInfo.getLockName()
    28  *          and ThreadInfo.getLockOwnerName()
    28  *          and ThreadInfo.getLockOwnerName()
    29  * @author  Mandy Chung
    29  * @author  Mandy Chung
    30  * @author  Jaroslav Bachorik
    30  * @author  Jaroslav Bachorik
    31  *
    31  *
       
    32  * @library /lib/testlibrary
       
    33  * @build jdk.testlibrary.*
    32  * @run main/othervm Locks
    34  * @run main/othervm Locks
    33  */
    35  */
    34 
    36 
    35 import java.lang.management.*;
    37 import java.lang.management.*;
    36 import java.util.concurrent.Phaser;
    38 import java.util.concurrent.Phaser;
       
    39 import jdk.testlibrary.LockFreeLogManager;
    37 
    40 
    38 public class Locks {
    41 public class Locks {
    39     private static final Object objA = new Object();
    42     private static final Object objA = new Object();
    40     private static final Object objB = new Object();
    43     private static final Object objB = new Object();
    41     private static final Object objC = new Object();
    44     private static final Object objC = new Object();
    42     private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();
    45     private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean();
       
    46     private static final LockFreeLogManager logger = new LockFreeLogManager();
    43 
    47 
    44     private static boolean testFailed = false;
    48     private static boolean testFailed = false;
    45 
    49 
    46     private static String getLockName(Object lock) {
    50     private static String getLockName(Object lock) {
    47         if (lock == null) return null;
    51         if (lock == null) return null;
   124             this.p = p;
   128             this.p = p;
   125         }
   129         }
   126         public void run() {
   130         public void run() {
   127             synchronized(objA) {
   131             synchronized(objA) {
   128                 // stop here  for LockBThread to hold objB
   132                 // stop here  for LockBThread to hold objB
   129                 System.out.println("LockAThread about to block on objB");
   133                 log("LockAThread about to block on objB");
   130                 p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
   134                 p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
   131                 synchronized(objB) {
   135                 synchronized(objB) {
   132                     dummyCounter++;
   136                     dummyCounter++;
   133                 };
   137                 };
   134             }
   138             }
   135             p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
   139             p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
   136             System.out.println("LockAThread about to exit");
   140             log("LockAThread about to exit");
   137             // Make sure the current thread is not holding any lock
   141             // Make sure the current thread is not holding any lock
   138             assertNoLock(this);
   142             assertNoLock(this);
   139         }
   143         }
   140     }
   144     }
   141 
   145 
   145             super("LockBThread");
   149             super("LockBThread");
   146             this.p = p;
   150             this.p = p;
   147         }
   151         }
   148         public void run() {
   152         public void run() {
   149             synchronized(objB) {
   153             synchronized(objB) {
   150                 System.out.println("LockBThread about to block on objC");
   154                 log("LockBThread about to block on objC");
   151                 p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
   155                 p.arriveAndAwaitAdvance(); // Phase 1 (blocking)
   152                 // Signal main thread about to block on objC
   156                 // Signal main thread about to block on objC
   153                 synchronized(objC) {
   157                 synchronized(objC) {
   154                     dummyCounter++;
   158                     dummyCounter++;
   155                 };
   159                 };
   156             }
   160             }
   157             p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
   161             p.arriveAndAwaitAdvance(); // Phase 2 (blocking)
   158             System.out.println("LockBThread about to exit");
   162             log("LockBThread about to exit");
   159             // Make sure the current thread is not holding any lock
   163             // Make sure the current thread is not holding any lock
   160             assertNoLock(this);
   164             assertNoLock(this);
   161         }
   165         }
   162     }
   166     }
   163 
   167 
   164     private static WaitingThread waiter;
   168     private static WaitingThread waiter;
   165     private static Object ready = new Object();
   169     private static final Object ready = new Object();
   166     private static CheckerThread checker;
   170     private static CheckerThread checker;
   167     static class WaitingThread extends Thread {
   171     static class WaitingThread extends Thread {
   168         private final Phaser p;
   172         private final Phaser p;
   169 
   173 
   170         volatile boolean waiting = false;
   174         volatile boolean waiting = false;
   171 
   175 
   172         public WaitingThread(Phaser p) {
   176         public WaitingThread(Phaser p) {
   173             super("WaitingThread");
   177             super("WaitingThread");
   174             this.p = p;
   178             this.p = p;
   175         }
   179         }
       
   180         @Override
   176         public void run() {
   181         public void run() {
   177             synchronized(objC) {
   182             synchronized(objC) {
   178                 System.out.println("WaitingThread about to wait on objC");
   183                 log("WaitingThread about to wait on objC");
   179                 try {
   184                 try {
   180                     // Signal checker thread, about to wait on objC.
   185                     // Signal checker thread, about to wait on objC.
   181                     waiting = false;
   186                     waiting = false;
   182                     p.arriveAndAwaitAdvance(); // Phase 1 (waiting)
   187                     p.arriveAndAwaitAdvance(); // Phase 1 (waiting)
   183                     waiting = true;
   188                     waiting = true;
   186                     e.printStackTrace();
   191                     e.printStackTrace();
   187                     testFailed = true;
   192                     testFailed = true;
   188                 }
   193                 }
   189 
   194 
   190                 // block until CheckerThread finishes checking
   195                 // block until CheckerThread finishes checking
   191                 System.out.println("WaitingThread about to block on ready");
   196                 log("WaitingThread about to block on ready");
   192                 // signal checker thread that it is about acquire
   197                 // signal checker thread that it is about acquire
   193                 // object ready.
   198                 // object ready.
   194                 p.arriveAndAwaitAdvance(); // Phase 2 (waiting)
   199                 p.arriveAndAwaitAdvance(); // Phase 2 (waiting)
   195                 synchronized(ready) {
   200                 synchronized(ready) {
   196                     dummyCounter++;
   201                     dummyCounter++;
   197                 };
   202                 }
   198             }
   203             }
   199             synchronized(objC) {
   204             synchronized(objC) {
   200                 try {
   205                 try {
   201                     // signal checker thread, about to wait on objC
   206                     // signal checker thread, about to wait on objC
   202                     waiting = false;
   207                     waiting = false;
   206                 } catch (InterruptedException e) {
   211                 } catch (InterruptedException e) {
   207                     e.printStackTrace();
   212                     e.printStackTrace();
   208                     testFailed = true;
   213                     testFailed = true;
   209                 }
   214                 }
   210             }
   215             }
   211             System.out.println("WaitingThread about to exit waiting on objC 2");
   216             log("WaitingThread about to exit waiting on objC 2");
   212         }
   217         }
   213 
   218 
   214         public void waitForWaiting() {
   219         public void waitForWaiting() {
   215             p.arriveAndAwaitAdvance();
   220             p.arriveAndAwaitAdvance();
   216             while (!waiting) {
   221             while (!waiting) {
   319     }
   324     }
   320 
   325 
   321     private static ThreadInfo findOwnerInfo(ThreadInfo[] infos, String lock)
   326     private static ThreadInfo findOwnerInfo(ThreadInfo[] infos, String lock)
   322             throws Exception {
   327             throws Exception {
   323         ThreadInfo ownerInfo = null;
   328         ThreadInfo ownerInfo = null;
   324         for (int i = 0; i < infos.length; i++) {
   329         for (ThreadInfo info : infos) {
   325             String blockedLock = infos[i].getLockName();
   330             String blockedLock = info.getLockName();
   326             if (lock.equals(blockedLock)) {
   331             if (lock.equals(blockedLock)) {
   327                 long threadId = infos[i].getLockOwnerId();
   332                 long threadId = info.getLockOwnerId();
   328                 if (threadId == -1) {
   333                 if (threadId == -1) {
   329                     throw new RuntimeException("TEST FAILED: " +
   334                     throw new RuntimeException("TEST FAILED: " +
   330                             lock + " expected to have owner");
   335                             lock + " expected to have owner");
   331                 }
   336                 }
   332                 for (int j = 0; j < infos.length; j++) {
   337                 for (int j = 0; j < infos.length; j++) {
   353 
   358 
   354     private static void doCheck(ThreadInfo[] infos, String lock, long[] expectedThreads)
   359     private static void doCheck(ThreadInfo[] infos, String lock, long[] expectedThreads)
   355             throws Exception {
   360             throws Exception {
   356         ThreadInfo ownerInfo = null;
   361         ThreadInfo ownerInfo = null;
   357         // Find the thread who is blocking on lock
   362         // Find the thread who is blocking on lock
   358         for (int i = 0; i < infos.length;  i++) {
   363         for (ThreadInfo info : infos) {
   359             String blockedLock = infos[i].getLockName();
   364             String blockedLock = info.getLockName();
   360             if (lock.equals(blockedLock)) {
   365             if (lock.equals(blockedLock)) {
   361                 System.out.print(infos[i].getThreadName() +
   366                 log("%s blocked on %s", info.getThreadName(), blockedLock);
   362                         " blocked on " + blockedLock);
   367                 ownerInfo = info;
   363                 ownerInfo = infos[i];
   368             }
   364             }
   369         }
       
   370         if (ownerInfo == null) {
       
   371             throw new RuntimeException("TEST FAILED: " +
       
   372                     "Can't retrieve ThreadInfo for the blocked thread");
   365         }
   373         }
   366 
   374 
   367         long[] threads = new long[10];
   375         long[] threads = new long[10];
   368         int count = 0;
   376         int count = 0;
   369         threads[count++] = ownerInfo.getThreadId();
   377         threads[count++] = ownerInfo.getThreadId();
   370         while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) {
   378         while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) {
   371             ownerInfo = findOwnerInfo(infos, lock);
   379             ownerInfo = findOwnerInfo(infos, lock);
   372             threads[count++] = ownerInfo.getThreadId();
   380             threads[count++] = ownerInfo.getThreadId();
   373             System.out.println(" Owner = " + ownerInfo.getThreadName() +
   381             log(" Owner = %s  id = %d",
   374                     " id = " + ownerInfo.getThreadId());
   382                     ownerInfo.getThreadName(),
       
   383                     ownerInfo.getThreadId()
       
   384             );
   375             lock = ownerInfo.getLockName();
   385             lock = ownerInfo.getLockName();
   376             System.out.print(ownerInfo.getThreadName() + " Id = " +
   386             log("%s Id = %d  blocked on %s",
   377                     ownerInfo.getThreadId() +
   387                     ownerInfo.getThreadName(),
   378                     " blocked on " + lock);
   388                     ownerInfo.getThreadId(),
   379         }
   389                     lock
   380         System.out.println();
   390             );
       
   391         }
       
   392         log("");
   381 
   393 
   382         if (count != expectedThreads.length) {
   394         if (count != expectedThreads.length) {
   383             throw new RuntimeException("TEST FAILED: " +
   395             throw new RuntimeException("TEST FAILED: " +
   384                     "Expected chain of threads not matched; current count =" + count);
   396                     "Expected chain of threads not matched; current count =" + count);
   385         }
   397         }
   386         for (int i = 0; i < count; i++) {
   398         for (int i = 0; i < count; i++) {
   387             if (threads[i] != expectedThreads[i]) {
   399             if (threads[i] != expectedThreads[i]) {
   388                 System.out.println("TEST FAILED: " +
   400                 log("TEST FAILED: Unexpected thread in the chain %s expected to be %s",
   389                         "Unexpected thread in the chain " + threads[i] +
   401                     threads[i],
   390                         " expected to be " + expectedThreads[i]);
   402                     expectedThreads[i]
   391             }
   403                 );
   392         }
   404             }
       
   405         }
       
   406     }
       
   407 
       
   408     private static void log(String format, Object ... args) {
       
   409         logger.log(format + "%n", args);
   393     }
   410     }
   394 }
   411 }