sun.misc.Unsafe介绍以及几种Counter方案性能对比
创建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