java Unsafe类的compareAndSwap方法

compareAndSwap是个原子方法,原理是CAS,即将内存中的值与期望值进行比较,如果相等,就将内存中的值修改成新值并返回true。

package com.java.magic.part4.exception;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

class Target{
	
	int intParam = 3;
	
	long longParam;
	
	String strParam;
}

public class UnsafeTest {
	
	private static Unsafe unsafe;
	
	static{
		try {
			Field field = Unsafe.class.getDeclaredField("theUnsafe");
			field.setAccessible(true);
			unsafe = (Unsafe)field.get(null);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		Class clazz = Target.class;
		Field[] fields = clazz.getDeclaredFields();
		System.out.println("fieldNameeeee:fieldOffset");
		for(Field f : fields){
			//获取属性偏移量,可以通过这个偏移量给属性设值
			System.out.println(f.getName()+" : "+unsafe.objectFieldOffset(f));
		}
		System.out.println("--------------------------------");
		Target target = new Target();
		Field intParam = clazz.getDeclaredField("intParam");
		int a = (Integer) intParam.get(target);
		System.out.println("intParam原始值:"+a);
		long intParamOffset = unsafe.objectFieldOffset(intParam);
		System.out.println("intParam实例变量偏移量:"+intParamOffset);
		//intParam实例变量偏移量是offset 原始值是3,我们要改成10
		System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10));
		System.out.println("intParam改变之后的值:"+target.intParam);
		
		System.out.println("--------------------------------");
		//这个时候已经改为10了,所以会返回false  
        System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10)); 
        
        System.out.println("--------------------------------");
        Field strParam = clazz.getDeclaredField("strParam");
        String str = (String) strParam.get(target);
        System.out.println("strParam原始值:"+str);
        long strParamOffset = unsafe.objectFieldOffset(strParam);
        System.out.println("strParam实例变量的偏移量是:"+strParamOffset);
        System.out.println(unsafe.compareAndSwapObject(target, strParamOffset, null, "5")); 
		System.out.println("strParam改变之后的值:"+target.strParam);
		
		
	}
	

}

 运行结果如下:


compareAndSwapInt是通过调用本地方法根据字段偏移去修改对象属性的. 

可以看到int是4个字节的偏移量,long是8个字节的偏移量
注意:Unsafe的对象不能直接new,这里通过反射去获取Unsafe里面的私有成员变量theUnsafe

猜你喜欢

转载自weigang-gao.iteye.com/blog/2324691