Last active
August 20, 2018 14:41
-
-
Save lotabout/7224af60e26d912ab04722e2ddb9b20f to your computer and use it in GitHub Desktop.
Test the performance of different concurrency mechanism.
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 sun.misc.Unsafe; | |
import java.lang.reflect.Field; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.concurrent.atomic.AtomicInteger; | |
import java.util.concurrent.atomic.LongAdder; | |
public class ConcurrencyTest { | |
private enum TestType { | |
LONG_ADDER, | |
INC_AND_GET, | |
GET_AND_ADD, | |
CAS, | |
SYNC, | |
} | |
public static class LongAdderThread extends Thread { | |
private static LongAdder longAdder = new LongAdder(); | |
public void run() { | |
int i = 1; | |
while(i <= LOOP_COUNT) { | |
longAdder.increment(); | |
i++; | |
} | |
} | |
} | |
public static class IncrementAndGetThread extends Thread { | |
private static AtomicInteger atomicInteger = new AtomicInteger(0); | |
public void run() { | |
int i = 1; | |
while(i <= LOOP_COUNT) { | |
atomicInteger.incrementAndGet(); | |
i++; | |
} | |
} | |
} | |
public static class GetAndAddThread extends Thread { | |
private static volatile int cas = 0; | |
private static long casOffset; | |
private static Unsafe UNSAFE; | |
static { | |
try { | |
@SuppressWarnings("ALL") | |
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); | |
theUnsafe.setAccessible(true); | |
UNSAFE = (Unsafe) theUnsafe.get(null); | |
casOffset = UNSAFE.staticFieldOffset(GetAndAddThread.class.getDeclaredField("cas")); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public void atomicInteger() { | |
UNSAFE.getAndAddInt(this, casOffset, 1); | |
} | |
public void run() { | |
int i = 1; | |
while(i <= LOOP_COUNT) { | |
atomicInteger(); | |
i++; | |
} | |
} | |
} | |
public static class CASThread extends Thread { | |
private static volatile int cas = 0; | |
private static long casOffset; | |
private static Unsafe UNSAFE; | |
static { | |
try { | |
@SuppressWarnings("ALL") | |
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); | |
theUnsafe.setAccessible(true); | |
UNSAFE = (Unsafe) theUnsafe.get(null); | |
casOffset = UNSAFE.staticFieldOffset(CASThread.class.getDeclaredField("cas")); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
public void cas() { | |
boolean bl = false; | |
int tmp; | |
while (!bl) { | |
tmp = cas; | |
bl = UNSAFE.compareAndSwapInt(CASThread.class, casOffset, tmp, tmp + 1); | |
} | |
} | |
public void run() { | |
int i = 1; | |
while(i <= LOOP_COUNT) { | |
cas(); | |
i++; | |
} | |
} | |
} | |
public static class SynchronizedThread extends Thread { | |
private static int $synchronized = 0; | |
public void run() { | |
int i = 1; | |
while(i <= LOOP_COUNT) { | |
synchronized (SynchronizedThread.class) { | |
$synchronized ++; | |
} | |
i++; | |
} | |
} | |
} | |
public static long test(int threadCount, TestType type) { | |
List<Thread> threads = new ArrayList<>(); | |
for (int i = 1; i <= threadCount; i++) { | |
Thread thread = null; | |
switch (type) { | |
case LONG_ADDER: | |
thread = new LongAdderThread(); | |
break; | |
case INC_AND_GET: | |
thread = new IncrementAndGetThread(); | |
break; | |
case GET_AND_ADD: | |
thread = new GetAndAddThread(); | |
break; | |
case CAS: | |
thread = new CASThread(); | |
break; | |
case SYNC: | |
thread = new SynchronizedThread(); | |
break; | |
} | |
threads.add(thread); | |
} | |
long start = System.currentTimeMillis(); | |
for (Thread thread: threads) { | |
thread.start(); | |
} | |
for (Thread thread : threads) { | |
try { | |
thread.join(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
return System.currentTimeMillis() - start; | |
} | |
private static int LOOP_COUNT = 10_000_000; | |
public static void main(String[] args) { | |
for (int thread_count=1; thread_count < 50; thread_count++) { | |
for (int thousands = 1; thousands<= 1000; thousands += 1) { | |
LOOP_COUNT = 1000 * thousands; | |
System.out.println("" + thread_count + "," | |
+ thousands + "," | |
+ test(thread_count, TestType.CAS) + "," | |
+ test(thread_count, TestType.SYNC)); | |
} | |
} | |
// int THREAD_COUNT = 50; | |
// System.out.println("" + test(THREAD_COUNT, TestType.LONG_ADDER) + "\t" | |
// + test(THREAD_COUNT, TestType.INC_AND_GET) + "\t" | |
// + test(THREAD_COUNT, TestType.GET_AND_ADD) + "\t" | |
// + test(THREAD_COUNT, TestType.CAS) + "\t" | |
// + test(THREAD_COUNT, TestType.SYNC)); | |
} | |
} |
Author
lotabout
commented
Aug 19, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment