• sun.misc.Unsafe介绍以及几种Counter方案性能对比


    创建unsafe对象

        private static Unsafe getUnsafe() {
            try {
                Field f = Unsafe.class.getDeclaredField("theUnsafe");
                f.setAccessible(true);
                return (Unsafe) f.get(null);
            } catch (Exception e) {
                //e.printStackTrace();
                throw new RuntimeException(e);
            } 
        }

    测试unsafe

             Unsafe unsafe = Unsafe.getUnsafe();
             //java.lang.SecurityException
             System.out.println(unsafe);
             
             Unsafe unsafe = getUnsafe();
             System.out.println(unsafe);//正确

    几种Counter方案性能对比

    Counter接口

        interface Counter {
            void increment();
            long getCounter();
        }

    创建线程方法

        static class CounterRunnable implements Runnable {
            private final Counter counter;
            private final int num;
            
            CounterRunnable(Counter counter, int num) {
                this.counter = counter;
                this.num = num;
            }
            
            @Override
            public void run() {
                for(int i = 0; i < num; i++) {
                    counter.increment();
                }
            }
        }

    第一种:非原子性的

        static class StupidCounter implements Counter{
            private long counter = 0;
            
            @Override
            public void increment() {
                counter++;
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }

    第二种:使用synchronized修饰的

        static class SynCounter implements Counter{
            private long counter = 0;
            
            @Override
            public synchronized void increment() {
                counter++;
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }

    第三种:使用显示锁

        static class LockCounter implements Counter{
            private long counter = 0;
            private final Lock lock = new ReentrantLock();
            
            @Override
            public void increment() {
                try {
                    lock.lock();
                    counter++;
                } finally {
                    lock.unlock();
                }
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }

    第四种:使用 Atomicxxx

        static class AtomicCounter implements Counter{
            private AtomicLong counter = new AtomicLong();
            
            @Override
            public void increment() {
                counter.getAndIncrement();
            }
    
            @Override
            public long getCounter() {
                return counter.get();
            }
        }

    第五种:使用CAS方式

        static class CASCounter implements Counter{
            private volatile long counter = 0;
            private Unsafe unsafe;
            private long offset;//偏移量
            
            CASCounter() throws Exception {
                unsafe = getUnsafe();
                offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("counter"));
            }
            
            @Override
            public synchronized void increment() {
                long current = counter;
                while(!unsafe.compareAndSwapLong(this, offset, current, current + 1)) {
                    current = counter;
                }
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }

    测试结果:

        public static void main(String[] args) throws Exception {
            ExecutorService service = Executors.newFixedThreadPool(1000);
            Counter counter = new StupidCounter();
            long start = System.currentTimeMillis();
            for(int i = 0; i < 1000; i++) {
                service.execute(new CounterRunnable(counter, 10000));
            }
            
            service.shutdown();
            service.awaitTermination(1, TimeUnit.HOURS);
            long end = System.currentTimeMillis();
            System.out.println("Counter result:" + counter.getCounter());
            System.out.println("Time passed in ms:" + (end - start));
        }

    第一种:

    Counter result:9937444
    Time passed in ms:128

    第二种:

    Counter result:10000000
    Time passed in ms:567

    第三种:

    Counter result:10000000
    Time passed in ms:294

    第四种:

    Counter result:10000000
    Time passed in ms:298

    第五种:

    Counter result:10000000
    Time passed in ms:626
  • 相关阅读:
    CET成绩批量查询
    c++常用库简介
    1985年以来微软、苹果、Google赚了多少钱?
    试试PT建站脚本
    补门~
    网站提交大全
    uniapp接入人身核验小程序
    【odoo】【知识杂谈】关于菜单及记录规则中“非”计算的改造
    【odoo】【知识杂谈】关于odoo二开模块规范的一点思考
    mysql拒绝访问
  • 原文地址:https://www.cnblogs.com/zheaven/p/13175486.html
Copyright © 2020-2023  润新知