package org.juxtapose.streamline.laboration.locktest; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class LockTest { /** * One thread counts to 5 million = 70 ms. This is 14 ns per iteration or 42 clock cycles. * One thread counts to 5 million with synchronized increment = 1140 ms. This is 228 ns per iteration or 684 clock cycles. * Two thread counts to 5 million with synchronized increment = 2527 ms. This is 505 ns per iteration or (1515 clock cycles). * One thread counts to 5 million with CAS = 500 ms. This is 100 ns per iteration or (300 clock cycles). * Two thread counts to 5 million with CAS = 979 ms. This is 195 ns per iteration or (587 clock cycles). * One thread counts to 5 million with volatile = 357 ms. This is 71 ns per iteration or (214 clock cycles). * Two thread counts to 5 million with volatile = 1231 ms. This is 246 ns per iteration or (738 clock cycles). * One thread counts to 5 million with contextswitch = 14221 ms. This is 2844 ns per iteration or (8532 clock cycles). * Two thread counts to 5 million with contextswitch = 10221 ms. This is 2044 ns per iteration or (6132 clock cycles). * * Since it is always slower do do two threads it seams that there is some sort of validation/invalidation flag that is being considered when * memory barriers decide on weather or not to do a memory flush. * **/ static long startTime; static volatile long counter = 0l; static Object mutex = new Object(); static ExecutorService execService = new ThreadPoolExecutor( 1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(5048576) ); public static void main( String[] args ) { Thread t1 = getUpdateThread(); Thread t2 = getUpdateThread(); startTime = System.nanoTime(); t1.start(); t2.start(); // while( counter < 5000000 ) // { // synchronized( mutex ) // { // counter++; // } // } // // finish(); } public static Thread getUpdateThread() { Runnable run = new Runnable(){ @Override public void run() { // while( counter.incrementAndGet() < 5000000 ) // { // // } while( true ) { // post( new Runnable() // { // @Override // public void run() // { //// System.out.println("executing "+counter); counter++; if( counter == 5000000 ) finish(); // } // }); // synchronized (mutex) // { // } } } }; Thread t = new Thread( run ); return t; } public static void finish() { long endTime = System.nanoTime(); System.out.println("It took: "+((endTime-startTime)/100000)+" ms"); System.exit( 1 ); } public static void post(Runnable inRunnable) { execService.execute( inRunnable ); } }