java多线程之-CAS无锁-unsafe理解
1.背景
这一节我们来学习一下unsafe对象
2.案例
1.自定义一个获取unsafe对象的类
package com.ldp.demo07Unfase; import sun.misc.Unsafe; import java.lang.reflect.Field; /** * @author 姿势帝-博客园 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 02/19 10:17 * @description */ public class MyUnsafeAccessor { static Unsafe unsafe; static { try { // Unsafe 对象中的 private static final Unsafe theUnsafe; Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafe = (Unsafe) theUnsafe.get(null); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static Unsafe getUnsafe() { return unsafe; } }
2.定义一个普通的业务对象
@Data @Accessors(chain = true) public class User { private int id; private String name; private Integer age; }
3.测试
/** * 测试自定义的unsafe对象 * <p> * 输出结果: * User(id=100, name=张无忌, age=18) * * @param args * @throws NoSuchFieldException */ public static void main(String[] args) throws NoSuchFieldException { // 反射获取字段 Field idField = User.class.getDeclaredField("id"); Field nameField = User.class.getDeclaredField("name"); Field ageField = User.class.getDeclaredField("age"); Unsafe unsafe = MyUnsafeAccessor.getUnsafe(); // 获取成员变量的偏移量 long idOffset = unsafe.objectFieldOffset(idField); long nameOffset = unsafe.objectFieldOffset(nameField); long ageOffset = unsafe.objectFieldOffset(ageField); User user = new User(); // 使用CAS替换值 unsafe.compareAndSwapInt(user, idOffset, 0, 100); unsafe.compareAndSwapObject(user, nameOffset, null, "张无忌"); unsafe.compareAndSwapObject(user, ageOffset, null, 18); // 输出对象,看值是否设置正确 System.out.println(user); }