Unsafe在一个例子

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unsafe在一个例子相关的知识,希望对你有一定的参考价值。

Java和C++语言的一个重要区别就是Java中我们无法直接操作一块内存区域,不能像C++中那样可以自己申请内存和释放内存。Java中的Unsafe类为我们提供了类似C++手动管理内存的能力,不建议使用该类

public class UnsafeTest {

    public static void main(String[] args) throws Exception {
        ExecutorService service = Executors.newFixedThreadPool(1000);
        Counter counter = new CASCounter();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            service.submit(new CounterRunnable(counter, 10000));
        }
        service.shutdown();
        service.awaitTermination(1, TimeUnit.HOURS);
        System.out.println("counter : " + counter.getCount());
        System.out.println("time elapse : " + (System.currentTimeMillis() - start));

    }

    public static Unsafe getUnsafe() throws IllegalAccessException {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        return unsafe;
    }

    interface Counter {
        void increment();

        long getCount();
    }

    static class StupidCounter implements Counter {

        private long value = 0;

        @Override
        public void increment() {
            value++;
        }

        @Override
        public long getCount() {
            return value;
        }

    }

    static class SynCounter implements Counter {

        private long value = 0;

        @Override
        public synchronized void increment() {
            value++;
        }

        @Override
        public long getCount() {
            return value;
        }

    }

    static class LockCounter implements Counter {

        private long value = 0;

        private Lock lock = new ReentrantLock();

        @Override
        public void increment() {
            lock.lock();
            try {
                value++;
            } finally {
                lock.unlock();
            }
        }

        @Override
        public long getCount() {
            return value;
        }

    }

    static class AtomicCounter implements Counter {

        private AtomicLong value = new AtomicLong();

        @Override
        public void increment() {
            value.incrementAndGet();
        }

        @Override
        public long getCount() {
            return value.get();
        }

    }

    static class CASCounter implements Counter {

        private Unsafe unsafe;
        private long offset;
        private volatile long value = 0;

        CASCounter() throws Exception {
            unsafe = getUnsafe();
            offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("value"));
        }

        @Override
        public void increment() {
            long current = value;
            while (!unsafe.compareAndSwapLong(this, offset, value, value + 1)) {
                current = value;
            }
        }

        @Override
        public long getCount() {
            return value;
        }

    }

    static class CounterRunnable implements Runnable {
        Counter counter;
        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();
            }
        }
    }

}

 

以上是关于Unsafe在一个例子的主要内容,如果未能解决你的问题,请参考以下文章

Unsafe在一个例子

Java Unsafe 常用API 例子。

Java直接内存读写的例子

golang goroutine例子[golang并发代码片段]

如何创建片段以重复变量编号中的代码行

分享几个实用的代码片段(附代码例子)