import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
public class SyncVsAtomicVsLongAdder {
private static long count1 = 0;
private static AtomicLong count2 = new AtomicLong(0);
private static LongAdder count3 = new LongAdder();
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[100];// 控制线程数
int times = 10000;// 控制循环次数
// sync+long
Object lock = new Object();
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
synchronized (lock) {
count1++;
}
}
});
}
long start = System.currentTimeMillis();
for (Thread t : threads) t.start();
for (Thread t : threads) t.join();
long end = System.currentTimeMillis();
System.out.println("sync+long:" + count1 + ",time:" + (end - start));
// AtomicLong
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
count2.incrementAndGet();
}
});
}
start = System.currentTimeMillis();
for (Thread t : threads) t.start();
for (Thread t : threads) t.join();
end = System.currentTimeMillis();
System.out.println("AtomicLong:" + count2 + ",time:" + (end - start));
// LongAdder
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < times; j++) {
count3.increment();
}
});
}
start = System.currentTimeMillis();
for (Thread t : threads) t.start();
for (Thread t : threads) t.join();
end = System.currentTimeMillis();
System.out.println("LongAdder:" + count3 + ",time:" + (end - start));
}
}
实验一:线程数一百,循环一万次
结果一
sync+long:1000000,time:175
AtomicLong:1000000,time:55
LongAdder:1000000,time:108
结果二
sync+long:1000000,time:285
AtomicLong:1000000,time:104
LongAdder:1000000,time:98
结果三
sync+long:1000000,time:292
AtomicLong:1000000,time:79
LongAdder:1000000,time:76
实验二:线程数一百,循环十万次
结果一
sync+long:10000000,time:746
AtomicLong:10000000,time:439
LongAdder:10000000,time:192
结果二
sync+long:10000000,time:895
AtomicLong:10000000,time:312
LongAdder:10000000,time:173
结果三
sync+long:10000000,time:666
AtomicLong:10000000,time:388
LongAdder:10000000,time:176
实验三:线程数一千,循环一万次
结果一
sync+long:10000000,time:449
AtomicLong:10000000,time:787
LongAdder:10000000,time:399
结果二
sync+long:10000000,time:580
AtomicLong:10000000,time:465
LongAdder:10000000,time:448
结果三
sync+long:10000000,time:541
AtomicLong:10000000,time:522
LongAdder:10000000,time:583
实验四:线程数一千,循环十万次
结果一
sync+long:100000000,time:2860
AtomicLong:100000000,time:4700
LongAdder:100000000,time:1707
结果二
sync+long:100000000,time:2594
AtomicLong:100000000,time:4976
LongAdder:100000000,time:1608
结果三
sync+long:100000000,time:2626
AtomicLong:100000000,time:4685
LongAdder:100000000,time:2150
总结
synchronized—重量级锁;Atomic—自旋锁(CAS);LongAdder—分段自旋锁。因此该实验其实就是三种锁在不同场景下的性能对比。
竞争不激烈,建议使用自旋锁。
竞争激烈,建议使用重量级锁。
循环次数越高,分段自旋锁的性能优势越明显。