概述
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;@Overridepublic String toString() {return "Teacher{" +"name='" + name + '\'' +", id=" + id +'}';}}
