Unsafe例子

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

(1)Unsafe对int,long ,Object的CAS操作

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();
            }
        }
    }

}

 (2)可以绕过构造函数实例化对象

public class UnsafePlayer {
    
    // 通过反射实例化Unsafe
    public static Unsafe getUnsafe() throws IllegalAccessException {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        return unsafe;
    }
    
    public static void main(String[] args) throws Exception {
        // 获取Unsafe
        Unsafe unsafe = getUnsafe();
        // 实例化Player
        Player player = (Player) unsafe.allocateInstance(Player.class);
        player.setName("li lei");
        System.out.println(player.getName());
    }
}

class Player {
    private String name;

    private Player() {
        
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

(3)直接修改内存的值

/**
 * 
  * 直接修改了Foo对象的current值
 */
public class UnsafeTest2 {

    // 通过反射实例化Unsafe
    public static Unsafe getUnsafe() throws IllegalAccessException {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        return unsafe;
    }

    public static void main(String[] args) throws Exception {
        Foo foo = new Foo();
        Unsafe unsafe = getUnsafe();
        Field field = Foo.class.getDeclaredField("current");
        unsafe.putInt(foo, unsafe.objectFieldOffset(field), 12);
        foo.work();
    }
}

class Foo {

    private int current = 10;

    public void work() {
        if (current == 12) {
            System.out.println(" I am working ");
        }
    }

}
原文地址:https://www.cnblogs.com/moris5013/p/11829412.html