Created
April 30, 2014 13:44
-
-
Save huxi/81c152a672d1b39aed64 to your computer and use it in GitHub Desktop.
Different synchronization variants compared
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.locks.*; | |
public class SynchronizedVsFairLock | |
{ | |
public static void main(String args[]) | |
throws InterruptedException | |
{ | |
int delay=1; | |
if(args.length>0) | |
{ | |
try | |
{ | |
delay=Integer.parseInt(args[0]); | |
} | |
catch(NumberFormatException ex) | |
{ | |
//ignore | |
} | |
} | |
else | |
{ | |
System.out.println("Usage: SynchronizedVsFairLock [delay in ms]"); | |
} | |
System.out.println("Environment:"); | |
System.out.println("delay = "+delay); | |
System.out.println("java.runtime.name = "+System.getProperty("java.runtime.name")); | |
System.out.println("java.runtime.version = "+System.getProperty("java.runtime.version")); | |
System.out.println("java.vendor = "+System.getProperty("java.vendor")); | |
System.out.println("java.version = "+System.getProperty("java.version")); | |
System.out.println("java.vm.name = "+System.getProperty("java.vm.name")); | |
System.out.println("java.vm.info = "+System.getProperty("java.vm.info")); | |
System.out.println("os.name = "+System.getProperty("os.name")); | |
System.out.println("os.version = "+System.getProperty("os.version")); | |
System.out.println("os.arch = "+System.getProperty("os.arch")); | |
System.out.println("##########################################"); | |
usingSynchronized(10, delay); | |
usingUnfairLock(10, delay); | |
usingFairLock(10, delay); | |
} | |
public static void execute(String text, Thread[] threads) | |
throws InterruptedException | |
{ | |
System.out.println("About to execute "+text+"..."); | |
int threadCount=threads.length; | |
for(int i=0;i<threadCount;i++) | |
{ | |
threads[i].start(); | |
} | |
Thread.sleep(10000); | |
for(int i=threadCount - 1 ; i>=0 ; i--) | |
{ | |
threads[i].interrupt(); | |
} | |
Thread.sleep(1000); // wait a moment for termination, too lazy for join ;) | |
} | |
public static void print(String text, Runnable[] runnables) | |
{ | |
System.out.println("Results for "+text+":"); | |
for(int i=0;i<runnables.length;i++) | |
{ | |
System.out.println("runnables["+i+"]: "+runnables[i]); | |
} | |
System.out.println("##########################################"); | |
} | |
public static void usingSynchronized(int threadCount, int delay) | |
throws InterruptedException | |
{ | |
Object lockObject=new Object(); | |
Runnable[] runnables=new Runnable[threadCount]; | |
Thread[] threads=new Thread[threadCount]; | |
for(int i=0;i<threadCount;i++) | |
{ | |
runnables[i]=new SynchronizedRunnable(lockObject, delay); | |
threads[i]=new Thread(runnables[i]); | |
} | |
String text="usingSynchronized"; | |
execute(text, threads); | |
print(text, runnables); | |
} | |
public static void usingUnfairLock(int threadCount, int delay) | |
throws InterruptedException | |
{ | |
Lock lock=new ReentrantLock(); | |
Runnable[] runnables=new Runnable[threadCount]; | |
Thread[] threads=new Thread[threadCount]; | |
for(int i=0;i<threadCount;i++) | |
{ | |
runnables[i]=new LockRunnable(lock, delay); | |
threads[i]=new Thread(runnables[i]); | |
} | |
String text="usingUnfairLock"; | |
execute(text, threads); | |
print(text, runnables); | |
} | |
public static void usingFairLock(int threadCount, int delay) | |
throws InterruptedException | |
{ | |
Lock lock=new ReentrantLock(true); | |
Runnable[] runnables=new Runnable[threadCount]; | |
Thread[] threads=new Thread[threadCount]; | |
for(int i=0;i<threadCount;i++) | |
{ | |
runnables[i]=new LockRunnable(lock, delay); | |
threads[i]=new Thread(runnables[i]); | |
} | |
String text="usingFairLock"; | |
execute(text, threads); | |
print(text, runnables); | |
} | |
public static class SynchronizedRunnable | |
implements Runnable | |
{ | |
private final Object lockObject; | |
private final int delay; | |
private int counter; | |
private boolean running; | |
public SynchronizedRunnable(Object lockObject, int delay) | |
{ | |
this.lockObject=lockObject; | |
this.delay=delay; | |
this.counter=0; | |
this.running=false; | |
} | |
public void run() | |
{ | |
running=true; | |
for(;;) | |
{ | |
synchronized(lockObject) | |
{ | |
counter++; | |
try | |
{ | |
Thread.sleep(delay); | |
} | |
catch(InterruptedException ex) | |
{ | |
break; | |
} | |
} | |
} | |
running=false; | |
} | |
public String toString() | |
{ | |
return "SynchronizedRunnable[counter="+counter+", running="+running+", delay="+delay+"]"; | |
} | |
} | |
public static class LockRunnable | |
implements Runnable | |
{ | |
private final Lock lock; | |
private final int delay; | |
private int counter; | |
private boolean running; | |
public LockRunnable(Lock lock, int delay) | |
{ | |
this.lock=lock; | |
this.delay=delay; | |
this.counter=0; | |
this.running=false; | |
} | |
public void run() | |
{ | |
running=true; | |
for(;;) | |
{ | |
lock.lock(); | |
try | |
{ | |
counter++; | |
Thread.sleep(delay); | |
} | |
catch(InterruptedException ex) | |
{ | |
break; | |
} | |
finally | |
{ | |
lock.unlock(); | |
} | |
} | |
running=false; | |
} | |
public String toString() | |
{ | |
return "LockRunnable[counter="+counter+", running="+running+", delay="+delay+"]"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment