Java基礎 sync+long、Atomic、LongAdder性能比較

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章