Java8 更快的原子类:LongAdder(笔记)

  • 更快的原子类:LongAdder

     大家对AtomicInteger的基本实现机制应该比较了解,它们是在一个死循环内,不断尝试修改目标值,知道修改成功,如果竞争不激烈,那么修改成功的概率就很高,否则,修改失败的概率就很高,在大量修改失败时,这些原子操作就会进行多次循环尝试,因此性能就会受到影响

     那么竞争激烈的时候,我们应该如何进一步提高系统性能呢?一种基本方案就是可以使用热点分离,将竞争的数据进行分解.基于这个思路,打击应该可以想到一种对传统AtomicInteger等原子类的改进方法,虽然在CAS操作中没有锁,但是像减少锁粒度这种分离热点的思路依然可以使用,一种可行的方案就是仿造ConcurrengHashMap,将热点数据分离,比如,可以将AtomicInteger的内部核心数据value分离成一个数组,每个线程访问时,通过哈希等算法映射到其中一个数字进行计数,而最终的计数结果,则为这个数组的求和累加,其中,热点数据value被分离成多个单元cell,每个cell独自维护内部的值,当前对象的实际值由所有的cell累计合成,这样,热点就进行了有效的分离,提高了并行度,LongAdder正是使用了这种思想.

  • 测试LongAdder,原子类以及同步锁性能测试
  • public class LongAdderDemo {
        private static final int MAX_THREADS = 3;
        private static final int TASK_COUNT = 3;
        private static final int TARGET_COUNT = 10000000;
    
        private AtomicLong acount = new AtomicLong(0L);
        private LongAdder lacount = new LongAdder();
        private long count = 0;
    
    
        private static CountDownLatch cdlsync = new CountDownLatch(TASK_COUNT);
        private static CountDownLatch cdlatomic = new CountDownLatch(TASK_COUNT);
        private static CountDownLatch cdladdr = new CountDownLatch(TASK_COUNT);
    
    
        protected synchronized long inc() {
            return ++count;
        }
    
        protected synchronized long getCount() {
            return count;
        }
    
        public class SyncThread implements Runnable {
            protected String name;
            protected long starttime;
            LongAdderDemo out;
    
            public SyncThread(long starttime, LongAdderDemo out) {
                this.starttime = starttime;
                this.out = out;
            }
    
            @Override
            public void run() {
                long v = out.getCount();
                while (v < TARGET_COUNT) {
                    v = out.inc();
                }
                long endtime = System.currentTimeMillis();
                System.out.println("SyncThread spend:" + (endtime - starttime) + "ms" + " v" + v);
                cdlsync.countDown();
            }
        }
    
        public void testSync() throws InterruptedException {
            ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
            long starttime = System.currentTimeMillis();
            SyncThread sync = new SyncThread(starttime, this);
            for (int i = 0; i < TASK_COUNT; i++) {
                exe.submit(sync);
            }
            cdlsync.await();
            exe.shutdown();
        }
    
        public class AtomicThread implements Runnable {
            protected String name;
            protected long starttime;
    
            public AtomicThread(long starttime) {
                this.starttime = starttime;
            }
    
            @Override
            public void run() {
                long v = acount.get();
                while (v < TARGET_COUNT) {
                    v = acount.incrementAndGet();
                }
                long endtime = System.currentTimeMillis();
                System.out.println("AtomicThread spend:" + (endtime - starttime) + "ms" + " v" + v);
                cdlatomic.countDown();
            }
        }
    
        public void testAtomic() throws InterruptedException {
            ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
            long starttime = System.currentTimeMillis();
            AtomicThread atomic = new AtomicThread(starttime);
            for (int i = 0; i < TASK_COUNT; i++) {
                exe.submit(atomic);
            }
            cdlatomic.await();
            exe.shutdown();
        }
    
        public class LongAdderThread implements Runnable {
            protected String name;
            protected long starttime;
    
            public LongAdderThread(long starttime) {
                this.starttime = starttime;
            }
    
            @Override
            public void run() {
                long v = lacount.sum();
                while (v < TARGET_COUNT) {
                    lacount.increment();
                    v = lacount.sum();
                }
                long endtime = System.currentTimeMillis();
                System.out.println("LongAdderThread spend:" + (endtime - starttime) + "ms" + " v" + v);
                cdladdr.countDown();
            }
    
        }
    
        public void testLongAdder() throws InterruptedException {
            ExecutorService exe = Executors.newFixedThreadPool(MAX_THREADS);
            long starttime = System.currentTimeMillis();
            LongAdderThread atomic = new LongAdderThread(starttime);
            for (int i = 0; i < TASK_COUNT; i++) {
                exe.submit(atomic);
            }
            cdladdr.await();
            exe.shutdown();
        }
    
        public static void main(String[] args) throws InterruptedException {
            LongAdderDemo demo = new LongAdderDemo();
            demo.testSync();
            demo.testAtomic();
            demo.testLongAdder();
        }
    }

    结果:

  • SyncThread spend:317ms v10000000
    SyncThread spend:317ms v10000001
    SyncThread spend:317ms v10000002
    AtomicThread spend:157ms v10000000
    AtomicThread spend:160ms v10000001
    AtomicThread spend:179ms v10000002
    LongAdderThread spend:202ms v10000001
    LongAdderThread spend:202ms v10000001
    LongAdderThread spend:203ms v10000001
    SyncThread spend:535ms v10000000
    SyncThread spend:536ms v10000001
    SyncThread spend:542ms v10000002
    AtomicThread spend:184ms v10000000
    AtomicThread spend:185ms v10000001
    AtomicThread spend:214ms v10000002
    LongAdderThread spend:209ms v10000000
    LongAdderThread spend:209ms v10000000
    LongAdderThread spend:212ms v10000001
    
    SyncThread spend:280ms v10000000
    SyncThread spend:280ms v10000001
    SyncThread spend:281ms v10000002
    AtomicThread spend:102ms v10000001
    AtomicThread spend:102ms v10000000
    AtomicThread spend:106ms v10000001
    LongAdderThread spend:209ms v10000000
    LongAdderThread spend:209ms v10000000
    LongAdderThread spend:210ms v10000000
    
    SyncThread spend:391ms v10000002
    SyncThread spend:391ms v10000001
    SyncThread spend:391ms v10000000
    AtomicThread spend:185ms v10000000
    AtomicThread spend:185ms v10000001
    AtomicThread spend:188ms v10000002
    LongAdderThread spend:210ms v10000000
    LongAdderThread spend:212ms v10000001
    LongAdderThread spend:215ms v10000002
    

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值