Skip to content

Instantly share code, notes, and snippets.

@acrylic-style
Last active February 3, 2021 08:18
Show Gist options
  • Save acrylic-style/fd175ee490125e8e8c0257f065a4c9ac to your computer and use it in GitHub Desktop.
Save acrylic-style/fd175ee490125e8e8c0257f065a4c9ac to your computer and use it in GitHub Desktop.
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@SuppressWarnings("unused")
public class Main {
private static final int COUNT = 100000000;
private static final Integer[] unsafeArray = new Integer[1];
private static final Integer[] array = new Integer[1];
private static final Integer[] lockedReadWriteArray = new Integer[1];
private static final Integer[] lockedArray = new Integer[1];
private static final ReentrantLock lock = new ReentrantLock();
private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static final AtomicReferenceArray<Integer> atomicArray = new AtomicReferenceArray<>(new Integer[1]);
private static final AtomicReference<Integer[]> atomicReference = new AtomicReference<>(new Integer[1]);
private static final Map<Integer, Integer> MAP = new HashMap<>();
private static final AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(1);
public static void main(String[] args) throws InterruptedException {
System.out.println("Initializing");
for (int i = 0; i < 1000000; i++) {
System.currentTimeMillis();
}
System.out.println("Count: " + COUNT);
long writeTime1 = runTask("Write: no synchronization", Main::write0);
long writeTime2 = runTask("Write: synchronized", Main::write1);
long writeTime3 = runTask("Write: AtomicReferenceArray", Main::write2);
long writeTime4 = runTask("Write: AtomicReference", Main::write3);
long writeTime5 = runTask("Write: Integer Map", Main::write4);
long writeTime6 = runTask("Write: AtomicIntegerArray", Main::write5);
long writeTime7 = runTask("Write: ReentrantReadWriteLock", Main::write6);
long writeTime8 = runTask("Write: ReentrantLock", Main::write7);
long readTime1 = runTask("Read: no synchronization", Main::read0);
long readTime2 = runTask("Read: synchronized", Main::read1);
long readTime3 = runTask("Read: AtomicReferenceArray", Main::read2);
long readTime4 = runTask("Read: AtomicReference", Main::read3);
long readTime5 = runTask("Read: Integer Map", Main::read4);
long readTime6 = runTask("Read: AtomicIntegerArray", Main::read5);
long readTime7 = runTask("Read: ReentrantReadWriteLock", Main::read6);
long readTime8 = runTask("Read: ReentrantLock", Main::read7);
System.out.println("========== Results (Write Time / Read Time) ==========");
printResult("No synchronization", writeTime1, readTime1);
printResult("Synchronized", writeTime2, readTime2);
printResult("AtomicReferenceArray", writeTime3, readTime3);
printResult("AtomicReference" , writeTime4, readTime4);
printResult("Integer Map", writeTime5, readTime5);
printResult("AtomicIntegerArray", writeTime6, readTime6);
printResult("ReentrantReadWriteLock", writeTime7, readTime7);
printResult("ReentrantLock", writeTime8, readTime8);
}
public static void printResult(String name, long write, long read) {
System.out.println(name + ": " + write + "ms / " + read + "ms (Total Time: " + (write + read) + "ms)");
}
public static long runTask(String name, Runnable runnable) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(8);
long start = System.currentTimeMillis();
for (int i = 0; i < 32; i++) {
executor.submit(() -> {
for (int j = 0; j < COUNT / 32; j++) {
runnable.run();
}
});
}
executor.shutdown();
//noinspection ResultOfMethodCallIgnored
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
long end = System.currentTimeMillis();
System.out.println("'" + name + "' finished in " + (end - start) + "ms");
return end - start;
}
// ----- write -----
public static void write0() {
unsafeArray[0] = 1;
}
public static synchronized void write1() {
array[0] = 1;
}
public static void write2() {
atomicArray.set(0, 1);
}
public static void write3() {
atomicReference.get()[0] = 1;
}
public static void write4() {
MAP.put(0, 1);
}
public static void write5() {
atomicIntegerArray.set(0, 1);
}
public static void write6() {
readWriteLock.writeLock().lock();
lockedReadWriteArray[0] = 1;
readWriteLock.writeLock().unlock();
}
public static void write7() {
lock.lock();
lockedReadWriteArray[0] = 1;
lock.unlock();
}
// ----- read -----
public static void read0() {
int ignored = unsafeArray[0];
}
public static synchronized void read1() {
int ignored = array[0];
}
public static void read2() {
int ignored = atomicArray.get(0);
}
public static void read3() {
int ignored = atomicReference.get()[0];
}
public static void read4() {
int ignored = MAP.get(0);
}
public static void read5() {
int ignored = atomicIntegerArray.get(0);
}
public static void read6() {
readWriteLock.readLock().lock();
int ignored = lockedReadWriteArray[0];
readWriteLock.readLock().unlock();
}
public static void read7() {
lock.lock();
int ignored = lockedReadWriteArray[0];
lock.unlock();
}
}
========== Results (Write Time / Read Time) ==========
No synchronization: 147ms / 48ms (Total Time: 195ms)
Synchronized: 2250ms / 2293ms (Total Time: 4543ms)
AtomicReferenceArray: 1913ms / 71ms (Total Time: 1984ms)
AtomicReference: 1618ms / 55ms (Total Time: 1673ms)
Integer Map: 1638ms / 74ms (Total Time: 1712ms)
AtomicIntegerArray: 1954ms / 52ms (Total Time: 2006ms)
ReentrantReadWriteLock: 1894ms / 16591ms (Total Time: 18485ms)
ReentrantLock: 1734ms / 1795ms (Total Time: 3529ms)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment