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