/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/licenses/publicdomain */ import java.util.concurrent.*; import java.util.concurrent.locks.*; import java.util.concurrent.atomic.*; import java.util.*; public final class ContextSwitchTest { static final int iters = 1000000; static AtomicReference turn = new AtomicReference(); public static void main(String[] args) throws Exception { test(); test(); test(); } static void test() throws Exception { MyThread a = new MyThread(); MyThread b = new MyThread(); a.other = b; b.other = a; turn.set(a); long startTime = System.nanoTime(); a.start(); b.start(); a.join(); b.join(); long endTime = System.nanoTime(); int np = a.nparks + b.nparks; System.out.println("Average time: " + ((endTime - startTime) / np) + "ns"); } static final class MyThread extends Thread { volatile Thread other; volatile int nparks; public void run() { final AtomicReference t = turn; final Thread other = this.other; if (turn == null || other == null) throw new NullPointerException(); int p = 0; for (int i = 0; i < iters; ++i) { while (!t.compareAndSet(other, this)) { LockSupport.park(); ++p; } LockSupport.unpark(other); } LockSupport.unpark(other); nparks = p; System.out.println("parks: " + p); } } }