从数字递增看锁与无锁
About 1 min
测试用例
sync-1
public class IncrementMain {
private final static int concurrency = 1000;
private final static int times = 100000;
private static volatile int count = 0;
public static void main(String[] args) throws InterruptedException {
var threads = new Thread[concurrency];
for (int i = 0; i < concurrency; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
synchronized (IncrementMain.class) {
count++;
}
}
});
}
long start = System.currentTimeMillis();
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
long end = System.currentTimeMillis();
System.out.printf("result: %d, time: %d", count, end - start);
}
}
sync-2
public class IncrementMain {
private final static int concurrency = 1000;
private final static int times = 100000;
private static volatile int count = 0;
public static void main(String[] args) throws InterruptedException {
var threads = new Thread[concurrency];
for (int i = 0; i < concurrency; i++) {
threads[i] = new Thread(() -> {
synchronized (IncrementMain.class) {
for (int j = 0; j < times; j++) {
count++;
}
}
});
}
long start = System.currentTimeMillis();
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
long end = System.currentTimeMillis();
System.out.printf("result: %d, time: %d", count, end - start);
}
}
atomicInteger
import java.util.concurrent.atomic.AtomicInteger;
public class IncrementMain {
private final static int concurrency = 1000;
private final static int times = 100000;
private static final AtomicInteger count = new AtomicInteger();
public static void main(String[] args) throws InterruptedException {
var threads = new Thread[concurrency];
for (int i = 0; i < concurrency; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
count.incrementAndGet();
}
});
}
long start = System.currentTimeMillis();
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
long end = System.currentTimeMillis();
System.out.printf("result: %d, time: %d", count, end - start);
}
}
longAdder
import java.util.concurrent.atomic.LongAdder;
public class IncrementMain {
private final static int concurrency = 1000;
private final static int times = 100000;
private static final LongAdder count = new LongAdder();
public static void main(String[] args) throws InterruptedException {
var threads = new Thread[concurrency];
for (int i = 0; i < concurrency; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
count.increment();
}
});
}
long start = System.currentTimeMillis();
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
long end = System.currentTimeMillis();
System.out.printf("result: %d, time: %d", count, end - start);
}
}
输出结果如下:
并发量 | 循环次数 | 细粒度synchronized | 粗粒度synchronized | AtomicInteger | LongAdder |
---|---|---|---|---|---|
10 | 100000000 | 66260 | 6152 | 21264 | 1374 |
100 | 100000000 | 52281 | 5561 | 22562 | 1211 |
1000 | 100000 | 3484 | 514 | 1827 | 147 |
10000 | 100 | 663 | 497 | 488 | 511 |
关于synchronized
与ReentrantLock
的比较,可以参考: