test/demo/jvmti/Context.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, 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.

@@ -19,11 +19,10 @@
  * 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.
  */
 
-
 /*
  *
  *   Sample target application for jvmti demos
  *
  *     java Context [threadCount [iterationCount [sleepContention]]]

@@ -34,10 +33,12 @@
  *      sleepContention Time for main thread to sleep while holding lock
  *                      (creates monitor contention on all other threads)
  *
  */
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /* Used to sync up turns and keep track of who's turn it is */
 final class TurnChecker {
     int thread_index;
     TurnChecker(int thread_index) {
         this.thread_index = thread_index;

@@ -46,23 +47,25 @@
 
 /* Creates a bunch of threads that sequentially take turns */
 public final class Context extends Thread {
     /* Used to track threads */
     private static long startTime;
-    private static TurnChecker turn = new TurnChecker(-1);
-    private static int total_turns_taken;
 
     /* Used for each Context thread */
     private final int thread_count;
     private final int thread_index;
     private final int thread_turns;
+    private final TurnChecker turn;
+    private final AtomicInteger total_turns_taken;
 
     /* Main program */
     public static void main(String[] argv) throws InterruptedException {
         int default_thread_count = 5;
         int default_thread_turns = 10;
         int default_contention_sleep = 0;
+        AtomicInteger total_turns_taken = new AtomicInteger(0);
+        TurnChecker turn = new TurnChecker(-1);
         int expected_turns_taken;
         long sleepTime = 10L;
 
         /* Override defaults */
         if ( argv.length >= 1 ) {

@@ -81,16 +84,16 @@
                  + default_thread_count + " threads and "
                  + default_thread_turns + " turns per thread");
 
         /* Get all threads running (they will block until we set turn) */
         for (int i = 0; i < default_thread_count; i++) {
-            new Context(default_thread_count, i, default_thread_turns).start();
+            new Context(default_thread_count, i, default_thread_turns,
+                    total_turns_taken, turn).start();
         }
 
         /* Sleep to make sure thread_index 0 make it to the wait call */
         System.out.println("Context sleeping, so threads will start wait");
-        Thread.yield();
         Thread.sleep(sleepTime);
 
         /* Save start time */
         startTime = System.currentTimeMillis();
 

@@ -98,25 +101,28 @@
         synchronized (turn) {
             turn.thread_index = 0;
             turn.notifyAll();
         }
         System.out.println("Context sleeping, so threads can run");
-        Thread.yield();
         Thread.sleep(sleepTime);
 
         /* Wait for threads to finish (after everyone has had their turns) */
         while ( true ) {
             boolean done;
             done = false;
             synchronized (turn) {
-                if ( total_turns_taken == expected_turns_taken ) {
+                int current_total_turns_taken = total_turns_taken.get();
+                System.out.println("total_turns_taken =" +
+                        current_total_turns_taken +
+                        ";expected_turns_taken =" +
+                        expected_turns_taken);
+                if ( current_total_turns_taken == expected_turns_taken ) {
                     done = true;
                 }
                 /* Create some monitor contention by sleeping with lock */
                 if ( default_contention_sleep > 0 ) {
                     System.out.println("Context sleeping, to create contention");
-                    Thread.yield();
                     Thread.sleep((long)default_contention_sleep);
                 }
             }
             if ( done )
                 break;

@@ -134,17 +140,21 @@
         System.out.println("Context completed");
         System.exit(0);
     }
 
     /* Thread object to run */
-    Context(int thread_count, int thread_index, int thread_turns) {
+    Context(int thread_count, int thread_index, int thread_turns,
+            AtomicInteger total_turns_taken, TurnChecker turn) {
         this.thread_count = thread_count;
         this.thread_index = thread_index;
         this.thread_turns = thread_turns;
+        this.total_turns_taken = total_turns_taken;
+        this.turn = turn;
     }
 
     /* Main for thread */
+    @Override
     public void run() {
         int next_thread_index = (thread_index + 1) % thread_count;
         int turns_taken       = 0;
 
         try {

@@ -154,26 +164,31 @@
                 synchronized (turn) {
                     /* Keep waiting for our turn */
                     while (turn.thread_index != thread_index)
                         turn.wait();
                     /* MY TURN! Each thread gets thread_turns */
-                    total_turns_taken++;
                     turns_taken++;
-                    System.out.println("Turn #" + total_turns_taken
+                    System.out.println("Turn #"
+                                + total_turns_taken.incrementAndGet()
                                 + " taken by thread " + thread_index
                                 + ", " + turns_taken
                                 + " turns taken by this thread");
                     /* Give next thread a turn */
                     turn.thread_index = next_thread_index;
                     turn.notifyAll();
                 }
                 /* If we've had all our turns, break out of this loop */
                 if ( thread_turns == turns_taken ) {
+                    System.out.println("Loop end: thread got " + turns_taken
+                                        + " turns, expected " + thread_turns);
                     break;
                 }
             }
-        } catch (InterruptedException intEx) { /* skip */ }
+        } catch (InterruptedException intEx) {
+            System.out.println("Got an InterruptedException:" + intEx);
+            /* skip */ 
+        }
 
         /* Make sure we got all our turns */
         if ( thread_turns != turns_taken ) {
             System.out.println("ERROR: thread got " + turns_taken
                                         + " turns, expected " + thread_turns);