java无法访问操作系统底层API,诸如释放内存、原子操作、线程的挂起以及获取字段的内存地址等等。但是强大的java并非完全屏蔽了所有的入口,Unsafe类就可以提供上述功能的操作。下面例子只是简单的获取了Unsafe类,并实现了获取字段地址,以及初始化对象,并通过内存地址的原子访问给对象赋值的过程。
package com.my.springcloud.spark;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import sun.misc.Unsafe;
public class UnsafeUtil {
public static final Unsafe UNSAFE;
static {
try {
PrivilegedExceptionAction<Unsafe> action = new PrivilegedExceptionAction<Unsafe>() {
public Unsafe run() throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return ((Unsafe)theUnsafe.get(null));
}
};
UNSAFE = (Unsafe)AccessController.doPrivileged(action);
} catch (Exception e) {
throw new RuntimeException("load unsafe error", e);
}
}
public static Unsafe getUnsafe(){
return UNSAFE;
}
public static void main(String ...args) throws Exception{
long fieldAddress = UnsafeUtil.getUnsafe().objectFieldOffset(Person.class.getDeclaredField("name"));
System.out.println(fieldAddress);
Person obj = (Person)UnsafeUtil.getUnsafe().allocateInstance(Person.class);
UnsafeUtil.getUnsafe().compareAndSwapObject(obj, fieldAddress, null, "zhangsan");
System.out.println(obj.getName());
}
}
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
执行结果如下:
12
zhangsan