美文网首页
Unsafe介绍以及几种Counter方案性能对比

Unsafe介绍以及几种Counter方案性能对比

作者: yincb | 来源:发表于2019-04-16 00:34 被阅读0次

    一 、Unsafe介绍

    1.1 作用

    可以用来在任意内存地址位置处读写数据,支持一些CAS原子操作
    Java最初被设计为一种安全的受控环境。尽管如此,HotSpot还是包含了一个后门sun.misc.Unsafe,提供了一些可以直接操控内存和线程的底层操作。Unsafe被JDK广泛应用于java.nio和并发包等实现中,这个不安全的类提供了一个观察HotSpot JVM内部结构并且可以对其进行修改,但是不建议在生产环境中使用

    1.2 获取Unsafe实例

    Unsafe对象不能直接通过new Unsafe()或调用Unsafe.getUnsafe()获取,
    原因如下:
    不能直接new Unsafe(),原因是Unsafe被设计成单例模式,构造方法是私有的;
    不能通过调用Unsafe.getUnsafe()获取,因为getUnsafe被设计成只能从引导类加载器(bootstrap class loader)加载

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

    二、几种Counter方案性能对比

    public class UnsafeTest {
    
        public static void main(String[] args) throws Exception {
            ExecutorService service = Executors.newFixedThreadPool(1000);
            /**
             * StupiedCounter
             *      counter:9955671
             *      time:334
             */
            //Counter counter = new StupiedCounter();
    
            /**
             * SyncCounter
             *      counter:10000000
             *      time:1878
             */
            //Counter counter = new SyncCounter();
    
            /**
             * LockCounter
             *      counter:10000000
             *      time:413
             */
            // Counter counter = new LockCounter();
    
            /**
             * AtomicCounter
             *      counter:10000000
             *      time:287
             */
            // Counter counter = new AtomicCounter();
    
            /**
             * CasCounter
             *      counter:10000000
             *      time:638
             */
            Counter counter = new CasCounter();
    
            long start = System.currentTimeMillis();
            for (int i = 0; i < 1000; i++) {
                service.submit(new CounterRunner(counter,10000));
            }
            service.shutdown();
            service.awaitTermination(1, TimeUnit.HOURS);
            long end = System.currentTimeMillis();
            System.out.println("counter:"+counter.getCounter());
            System.out.println("time:"+(end-start));
        }
    
        private static Unsafe getUnsfe(){
            try {
                Field field = Unsafe.class.getDeclaredField("theUnsafe");
                field.setAccessible(true);
                return (Unsafe) field.get(null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        static class StupiedCounter implements Counter{
            private long counter = 0;
            @Override
            public void increment() {
                counter++;
            }
            @Override
            public long getCounter() {
                return counter;
            }
        }
    
        static class SyncCounter 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 Lock lock = new ReentrantLock();
    
            @Override
            public void increment() {
                try {
                    lock.lock();
                    counter++;
                }finally {
                    lock.unlock();
                }
    
            }
            @Override
            public long getCounter() {
                return counter;
            }
        }
    
        static class AtomicCounter implements Counter{
            private AtomicLong counter = new AtomicLong();
            @Override
            public void increment() {
                counter.incrementAndGet();
            }
            @Override
            public long getCounter() {
                return counter.get();
            }
        }
    
        static class CasCounter implements Counter{
            private long counter = 0;
            private Unsafe unsafe;
            private long offset;
    
            public CasCounter() throws NoSuchFieldException {
                this.unsafe = getUnsfe();
                this.offset = unsafe.objectFieldOffset(CasCounter.class.getDeclaredField("counter"));
            }
    
            @Override
            public void increment() {
                long current = counter;
                while (!unsafe.compareAndSwapLong(this,offset,current,current+1)){
                    current = counter;
                }
            }
            @Override
            public long getCounter() {
                return counter;
            }
        }
    
        interface Counter{
            void increment();
            long getCounter();
        }
    
        static class CounterRunner implements Runnable{
    
            private final Counter counter;
            private final int num;
    
            CounterRunner(Counter counter, int num) {
                this.counter = counter;
                this.num = num;
            }
    
            @Override
            public void run() {
                for (int i = 0; i < num; i++) {
                    counter.increment();
                }
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Unsafe介绍以及几种Counter方案性能对比

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