unsafe 锁与在jdk8中与其他的对比
package com.xiaodao.jdk8.thread.atomic; import com.sun.webkit.dom.CounterImpl; import sun.misc.Unsafe; import java.lang.reflect.Field; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Created by xiaodao */ public class UnsafeTest { /*** * stupidcounter result = 9111265 time passed = 233 *sync counter:counter result = 10000000 time passed = 633 *lockCounter: counter result = 10000000 time passed = 365 * atomic counter result = 10000000 time passed = 324 *cas counter : counter result = 10000000 time passed = 1645 * * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException, NoSuchFieldException { ExecutorService service = Executors.newFixedThreadPool(1000); Counter counter= new CasCounter(); long starTiem = System.currentTimeMillis(); for (int i = 0; i <1000 ; i++) { service.submit(new CounterRun(counter,10000)); } //线程池停止了.但是还是在运行 .在等10分钟. service.shutdown(); service.awaitTermination(10, TimeUnit.MINUTES); long endTiem = System.currentTimeMillis(); System.out.println("counter result = " + counter.getCounter()); System.out.println("time passed = "+ (endTiem-starTiem)); } public static Unsafe getUnsafe(){ try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); return (Unsafe)theUnsafe.get(null); } catch (Exception e) { throw new RuntimeException(e); } } interface Counter{ void increment(); long getCounter(); } /** * 实现类. */ static class StupidCounter 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 static Lock lock = new ReentrantLock(); private long counter = 0; @Override public void increment() { try { lock.lock(); counter++; } finally { lock.unlock(); } } @Override public long getCounter() { return counter; } } /** * atomic */ static class AtomicCounter implements Counter{ private AtomicInteger counter = new AtomicInteger(); @Override public void increment() { counter.incrementAndGet(); } @Override public long getCounter() { return counter.get(); } } /*** * */ static class CasCounter implements Counter{ private volatile long counter = 0; private Unsafe unsafe; private long offset; public CasCounter() throws NoSuchFieldException { unsafe=getUnsafe(); //.get offset 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; } } /** * fang放在线程池里跑的类. */ static class CounterRun implements Runnable{ private final Counter counter; private int num ; public CounterRun(Counter counter, int num) { this.counter = counter; this.num = num; } public Counter getCounter() { return counter; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public void run() { for (int i = 0; i <num ; i++) { counter.increment(); } } } }
* stupidcounter result = 9111265 time passed = 233 *sync counter:counter result = 10000000 time passed = 633 *lockCounter: counter result = 10000000 time passed = 365 * atomic counter result = 10000000 time passed = 324 *cas counter : counter result = 10000000 time passed = 1645
最终测试:
unsafe可以做哪些事情呢?
unsafe. 直接调用cpu缓存 c++ 汇编指令
跳过构造器直接创建类

public class UnsafefooTest { public static void main(String[] args) throws InstantiationException, ClassNotFoundException, IllegalAccessException { Unsafe unsafe = getUnsafe(); //unsafe 可以做一些邪恶的操作(直接开辟一个内存) 直接绕过构造方法创建对象. Simple o = (Simple) unsafe.allocateInstance(Simple.class); // System.out.println(o.get()); // System.out.println(o.getClass()); // System.out.println(o.getClass().getClassLoader()); } public static Unsafe getUnsafe(){ try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); return (Unsafe)theUnsafe.get(null); } catch (Exception e) { throw new RuntimeException(e); } } static class Simple{ private int l =0; public Simple(int l) { this.l = 1; System.out.println("========="); } public int get(){ return l; } } }
直接将对象的某个内存赋值
static class Simple1{ private int ACCESS_ALLOWED = 1; private boolean allow(){ return 40 == ACCESS_ALLOWED; } public void work(){ if(allow()){ System.out.println("i'm working by allowed ........"); } } } Simple1 simple1 = new Simple1(); Field access_allowed = simple1.getClass().getDeclaredField("ACCESS_ALLOWED"); unsafe.putInt(simple1,unsafe.objectFieldOffset(access_allowed),40); simple1.work();
然后下面的代码就可以执行...
部分底层代码如何调用的呢?
我们来看下unsafe.class 底层代码如何的,就用atomicInteger 来讲
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
jvm atomic.app 来做一些判断
1.首先判断 cpu是否是多核的 如果是加一个lock1 内存屏障 volatile
2.进行对比交换.是调用的汇编指令 cmpchg1
3.asm(汇编指令)