美文网首页
多线程中数字递增方式比较:sync atomic LongAdd

多线程中数字递增方式比较:sync atomic LongAdd

作者: Mr_Editor | 来源:发表于2021-02-28 14:49 被阅读0次

三种递增方式

  1. 递增时加锁 sync
  2. 原子类AtomicXXX (CAS)
  3. LongAdder

多线程对一个数进行递增这个事儿,我们工作中经常会碰上,比如在秒杀时候。那么这三种方式那种效率更搞一些呢?许多测试来看AtomicXXX比不上sync,但是在我的测试上来看,起码在测试条件下AtomicXXX比sync的效率要高很多。我们来看程序,count1,count2,cunt3分别是一下不同的方式实现递增,一上来启动了1000个线程(线程比较多,少了模拟不了高并发)

/**
 * @author haowq 2021/2/28 14:29
 */
public class PerformCompare {
    static AtomicLong count1 = new AtomicLong(0L);
    static long count2 = 0L;
    static LongAdder count3 = new LongAdder();

    public static void main(String[] args) throws InterruptedException {
        Thread[] threads = new Thread[1000];
        //方式1 sync
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int k = 0; k < 100000; k++) count1.incrementAndGet();
            });
        }

        long start = System.currentTimeMillis();

        for (Thread t : threads) t.start();

        for (Thread t : threads) t.join();

        long end = System.currentTimeMillis();
        System.out.println("Atomic: " + count1.get() + "  time: " + (end - start));
        System.out.println("-----------------------------------------------------");

        Object lock = new Object();

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int k = 0; k < 100000; k++) synchronized (lock){count2++;};
            });
        }
        start = System.currentTimeMillis();

        for (Thread t : threads) t.start();

        for (Thread t : threads) t.join();

        end = System.currentTimeMillis();
        System.out.println("Sync: " + count2 + "  time: " + (end - start));
        System.out.println("-----------------------------------------------------");

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int k = 0; k < 100000; k++) count3.increment();
            });
        }
        start = System.currentTimeMillis();

        for (Thread t : threads) t.start();

        for (Thread t : threads) t.join();

        end = System.currentTimeMillis();
        System.out.println("LongAddre: " + count3 + "  time: " + (end - start));
        System.out.println("-----------------------------------------------------");
    }
}
Atomic: 100000000  time: 1615
-----------------------------------------------------
Sync: 100000000  time: 3208
-----------------------------------------------------
LongAddre: 100000000  time: 560
-----------------------------------------------------

Process finished with exit code 0

结果

LongAdder > Atomic > Sync

分析

为什么Atomic 比Sync快呢,因为sync是要加锁的,有可能它要去操作系统申请重量级锁,所以sync 效率偏低,在这种情况下效率偏低
为什么LongAdder 比Atomic 效率更高呢?
LongAdder 的内部做了一个分段锁,类似于分段锁的概念。在它内部的时候,会把一个值放到一个数组中,比如说数组长度时4,最开始时0,1000个线程,250个线程锁在第一个数组元素里,以此类推,每一个都往上递增算出来结果加到一起。

相关文章

网友评论

      本文标题:多线程中数字递增方式比较:sync atomic LongAdd

      本文链接:https://www.haomeiwen.com/subject/kbegfltx.html