Unsafe功能介绍:
1: 访问并并设置对象特定位置的值,即使值是private的,依然可以访问到
private static class Node<E> {
volatile E item;
volatile Node<E> next;
private static final sun.misc.Unsafe UNSAFE;
private static final long itemOffset;
private static final long nextOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class k = Node.class;
itemOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("item"));
nextOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("next")); //通过类反射机制用成员变量的名字获取取对应的field ,
//然后再通过field来获取field在class中的偏移量
} catch (Exception e) {
throw new Error(e);
}
}
}
注:java 类的反射机制是一种不安全且耗时的操作,如无必要请不要使用
2:cas 操作,non-blocking算法(非阻塞算法)的基础
/**
* Atomically update Java variable to <tt>x</tt> if it is currently
* holding <tt>expected</tt>.
* @return <tt>true</tt> if successful
*/
public final native boolean compareAndSwapObject(Object o, long offset,
Object expected,
Object x);
/**
* Atomically update Java variable to <tt>x</tt> if it is currently
* holding <tt>expected</tt>.
* @return <tt>true</tt> if successful
*/
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);
CompareAndSwapInt在 jvm的内部实现:
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
Atomic::cmpxchg(x, addr, e)也是一个原子操作,通过比较缓存中的值与内存中的值是否相同来决定是否对其值进行更新
通常的用法是将其包含在循环中:可参考java atomicInteger源码
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
Unsafe功能调用实践:
可参考:http://jackycheng2007.iteye.com/blog/1473464
如果相查看Unsafe源码:可以下载开源的openJDK源码,在目录openjdk/jdk/src/share/classes是所有的java api源码
在openjdk/jdk/src/share/classes/sun/misc下可以查看源码。大部分功能都是native 方法
参考:
http://blog.csdn.net/aesop_wubo/article/details/7537278
未完...待续