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