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—分段自旋鎖。因此該實驗其實就是三種鎖在不同場景下的性能對比。
競爭不激烈,建議使用自旋鎖。
競爭激烈,建議使用重量級鎖。
循環次數越高,分段自旋鎖的性能優勢越明顯。