概述
Unsafe 对象提供了非常底层的,操作内存、线程的方法,Unsafe 对象不能直接调用,只能通过反射获得
创建Unsafe对象的两种方式
/**
* Unsafe工具类,生成Unsafe对象的两种方式
* @author hikktn
*/
public class UnsafeUtil {
/**
* 1. 通过反射获取Unsafe实例对象的字段
* @return
*/
public static final Unsafe getUnsafeInstance(){
Unsafe unsafe = null;
try {
// 字段名可能会变化,比如在Android的实现中时"THE_ONE",因此更推荐使用方式二
// 通过反射得到Unsafe中的单例字段
Field field = Unsafe.class.getDeclaredField("theUnsafe");
// 设置该Field为可访问
field.setAccessible(true);
// 通过get方法得到Undafe实例对象,传入null是因为该Field为static的
unsafe = (Unsafe) field.get(null);
} catch(NoSuchFieldException e) {
e.printStackTrace();
} catch(IllegalAccessException e) {
e.printStackTrace();
}
return unsafe;
}
/**
* 2. 通过反射调用构造方法来生成Unsafe实例,推荐用这种方式
* @param v
* @return
*/
public static final Unsafe getUnsafeInstance(Void v){
Unsafe unsafe = null;
try {
Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
unsafeConstructor.setAccessible(true);
// 通过默认的私有函数构造Unsafe实例
unsafe = unsafeConstructor.newInstance();
return unsafe;
} catch(NoSuchMethodException e) {
e.printStackTrace();
} catch(IllegalAccessException e) {
e.printStackTrace();
} catch(InstantiationException e) {
e.printStackTrace();
} catch(InvocationTargetException e) {
e.printStackTrace();
}
return unsafe;
}
}
创建实例Unsafe
public class UnsafeTest {
public static final Unsafe getUnsafeInstance() {
Unsafe unsafe = null;
try {
// 字段名可能会变化,比如在Android的实现中时"THE_ONE",因此更推荐使用方式二
// 通过反射得到Unsafe中的单例字段
Field field = Unsafe.class.getDeclaredField("theUnsafe");
// 设置该Field为可访问
field.setAccessible(true);
// 通过get方法得到Undafe实例对象,传入null是因为该Field为static的
unsafe = (Unsafe) field.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return unsafe;
}
public static void main(String[] args) {
Unsafe unsafe = getUnsafeInstance();
System.out.println(unsafe);
try {
// 获取域的偏移地址
long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));
long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
Teacher teacher = new Teacher();
// 执行cas操作
unsafe.compareAndSwapInt(teacher, idOffset, 0, 1);
unsafe.compareAndSwapObject(teacher, nameOffset, null, "hikktn");
System.out.println(teacher);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
class Teacher {
volatile String name;
volatile int id;
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}