首页 > 技术文章 > sun.misc.Unsafe介绍以及几种Counter方案性能对比

zheaven 2020-06-22 10:09 原文

创建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

 

推荐阅读