Java本是一种类型安全的语言,但sun.misc.unsafe却提供了一种不安全和“违规”的做法UnSafe类,UnSafe类的能实现很多神奇的功能,但掌握它却是非常的难,所以不要轻易使用。
CAS操作便是其提供的一个native的方法,Java种很多机制,如volatile变量,原子类等,都是利用其来实现的。下面通过一个例子来看看它是怎么使用的。
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeTest {
private static Unsafe unsafe;
static {
try {
//通过反射获取rt.jar下的Unsafe类
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
System.out.println("Get Unsafe instance occur error"+ e);
}
}
public static void main(String[] args) throws Exception
{
Class clazz = Target.class;
Field[] fields = clazz.getDeclaredFields();
System.out.println("fieldName:fieldOffset");
for (Field f : fields) {
// 获取属性偏移量,可以通过这个偏移量给属性设置
System.out.println(f.getName() + ":" + unsafe.objectFieldOffset(f));
}
Target target = new Target();
Field intFiled = clazz.getDeclaredField("intParam") ;
int a=(Integer)intFiled.get(target ) ;
System.out.println("原始值是:"+a);
//intParam的字段偏移是12 原始值是3 我们要改为10
System.out.println(unsafe.compareAndSwapInt(target, 12, 3, 10));
int b=(Integer)intFiled.get(target) ;
System.out.println("改变之后的值是:"+b);
//这个时候已经改为10了,所以会返回false
System.out.println(unsafe.compareAndSwapInt(target, 12, 3, 10));
System.out.println(unsafe.compareAndSwapObject(target, 24, null, "5"));
System.out.println(target.strParam);
}
}
class Target {
int intParam=3;
long longParam;
String strParam;
String strParam2;
}
通过对Unsafe类进行反编译,发现compareAndSwapXXX的函数原型如下:
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
var1:被作用的目标对象。
var2:被改的变量在var1中的偏移量
var3:变量var2的预测值
var4:变量var2如果等于预测值var3,则将其赋值为var4,并返回true,否则返回false
总结:利用Unsafe的cas操作可以实现许多无锁(Lock Free)操作和无锁算法,比如ConcurrentLinkedQueue中的非阻塞添加和移除算法等。.
Ref:http://huangyunbin.iteye.com/blog/1942369