概述
    Unsafe 对象提供了非常底层的,操作内存、线程的方法,Unsafe 对象不能直接调用,只能通过反射获得
    创建Unsafe对象的两种方式

    1. /**
    2. * Unsafe工具类,生成Unsafe对象的两种方式
    3. * @author hikktn
    4. */
    5. public class UnsafeUtil {
    6. /**
    7. * 1. 通过反射获取Unsafe实例对象的字段
    8. * @return
    9. */
    10. public static final Unsafe getUnsafeInstance(){
    11. Unsafe unsafe = null;
    12. try {
    13. // 字段名可能会变化,比如在Android的实现中时"THE_ONE",因此更推荐使用方式二
    14. // 通过反射得到Unsafe中的单例字段
    15. Field field = Unsafe.class.getDeclaredField("theUnsafe");
    16. // 设置该Field为可访问
    17. field.setAccessible(true);
    18. // 通过get方法得到Undafe实例对象,传入null是因为该Field为static的
    19. unsafe = (Unsafe) field.get(null);
    20. } catch(NoSuchFieldException e) {
    21. e.printStackTrace();
    22. } catch(IllegalAccessException e) {
    23. e.printStackTrace();
    24. }
    25. return unsafe;
    26. }
    27. /**
    28. * 2. 通过反射调用构造方法来生成Unsafe实例,推荐用这种方式
    29. * @param v
    30. * @return
    31. */
    32. public static final Unsafe getUnsafeInstance(Void v){
    33. Unsafe unsafe = null;
    34. try {
    35. Constructor<Unsafe> unsafeConstructor = Unsafe.class.getDeclaredConstructor();
    36. unsafeConstructor.setAccessible(true);
    37. // 通过默认的私有函数构造Unsafe实例
    38. unsafe = unsafeConstructor.newInstance();
    39. return unsafe;
    40. } catch(NoSuchMethodException e) {
    41. e.printStackTrace();
    42. } catch(IllegalAccessException e) {
    43. e.printStackTrace();
    44. } catch(InstantiationException e) {
    45. e.printStackTrace();
    46. } catch(InvocationTargetException e) {
    47. e.printStackTrace();
    48. }
    49. return unsafe;
    50. }
    51. }

    创建实例Unsafe

    1. public class UnsafeTest {
    2. public static final Unsafe getUnsafeInstance() {
    3. Unsafe unsafe = null;
    4. try {
    5. // 字段名可能会变化,比如在Android的实现中时"THE_ONE",因此更推荐使用方式二
    6. // 通过反射得到Unsafe中的单例字段
    7. Field field = Unsafe.class.getDeclaredField("theUnsafe");
    8. // 设置该Field为可访问
    9. field.setAccessible(true);
    10. // 通过get方法得到Undafe实例对象,传入null是因为该Field为static的
    11. unsafe = (Unsafe) field.get(null);
    12. } catch (NoSuchFieldException e) {
    13. e.printStackTrace();
    14. } catch (IllegalAccessException e) {
    15. e.printStackTrace();
    16. }
    17. return unsafe;
    18. }
    19. public static void main(String[] args) {
    20. Unsafe unsafe = getUnsafeInstance();
    21. System.out.println(unsafe);
    22. try {
    23. // 获取域的偏移地址
    24. long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));
    25. long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
    26. Teacher teacher = new Teacher();
    27. // 执行cas操作
    28. unsafe.compareAndSwapInt(teacher, idOffset, 0, 1);
    29. unsafe.compareAndSwapObject(teacher, nameOffset, null, "hikktn");
    30. System.out.println(teacher);
    31. } catch (NoSuchFieldException e) {
    32. e.printStackTrace();
    33. }
    34. }
    35. }
    36. class Teacher {
    37. volatile String name;
    38. volatile int id;
    39. @Override
    40. public String toString() {
    41. return "Teacher{" +
    42. "name='" + name + '\'' +
    43. ", id=" + id +
    44. '}';
    45. }
    46. }