test/demo/jvmti/Context.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2004, 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. --- 1,7 ---- /* ! * 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,29 **** * 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]]] --- 19,28 ----
*** 34,43 **** --- 33,44 ---- * 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,68 **** /* 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; /* 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; int expected_turns_taken; long sleepTime = 10L; /* Override defaults */ if ( argv.length >= 1 ) { --- 47,71 ---- /* Creates a bunch of threads that sequentially take turns */ public final class Context extends Thread { /* Used to track threads */ private static long startTime; /* 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,96 **** + 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(); } /* 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(); --- 84,99 ---- + 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, ! 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.sleep(sleepTime); /* Save start time */ startTime = System.currentTimeMillis();
*** 98,122 **** 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 ) { 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; --- 101,128 ---- synchronized (turn) { turn.thread_index = 0; turn.notifyAll(); } System.out.println("Context sleeping, so threads can run"); Thread.sleep(sleepTime); /* Wait for threads to finish (after everyone has had their turns) */ while ( true ) { boolean done; done = false; synchronized (turn) { ! 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.sleep((long)default_contention_sleep); } } if ( done ) break;
*** 134,150 **** System.out.println("Context completed"); System.exit(0); } /* Thread object to run */ ! Context(int thread_count, int thread_index, int thread_turns) { this.thread_count = thread_count; this.thread_index = thread_index; this.thread_turns = thread_turns; } /* Main for thread */ public void run() { int next_thread_index = (thread_index + 1) % thread_count; int turns_taken = 0; try { --- 140,160 ---- System.out.println("Context completed"); System.exit(0); } /* Thread object to run */ ! 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,179 **** 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 + " 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 ) { break; } } ! } catch (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); --- 164,194 ---- synchronized (turn) { /* Keep waiting for our turn */ while (turn.thread_index != thread_index) turn.wait(); /* MY TURN! Each thread gets thread_turns */ 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) { ! 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);