java并发学习32:unsafe使用

1、介绍

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

public class UnsafeAccessor {
    static Unsafeunsafe;
    static {
        try {    
			Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);   
        } catch (NoSuchFieldException|IllegalAccessExceptione) {
            thrownewError(e);     
        }  
    }
    static UnsafegetUnsafe() {
        returnunsafe;  
    }
}
2、unsage cas操作
@Data
class Student {
    volatile int id;
    volatile String name;
}

Unsafe unsafe = UnsafeAccessor.getUnsafe();
Field id = Student.class.getDeclaredField("id");
Field name = Student.class.getDeclaredField("name");

// 获得成员变量的偏移量
long  idOffset = UnsafeAccessor.unsafe.objectFieldOffset(id);
long nameOffset = UnsafeAccessor.unsafe.objectFieldOffset(name);
Student student = new Student();

// 使用 cas 方法替换成员变量的值
UnsafeAccessor.unsafe.compareAndSwapInt(student, idOffset, 0, 20);  // 返回 true
UnsafeAccessor.unsafe.compareAndSwapObject(student, nameOffset, null, "张三"); // 返回 true
System.out.println(student);
3、原子整数 Account 实现
class AtomicData {
    private volatile int data;
    static final Unsafe unsafe;
    static final long DATA_OFFSET;
    static {
        unsafe = UnsafeAccessor.getUnsafe();
        try {
            // data 属性在 DataContainer 对象中的偏移量,用于 Unsafe 直接访问该属性
         DATA_OFFSET = unsafe.objectFieldOffset(AtomicData.class.getDeclaredField("data")); 
        } catch (NoSuchFieldExceptione) {
            thrownewError(e);   
        }   
    }
    public AtomicData(intdata) {
        this.data = data;
    }
    public void decrease(intamount) {
        intoldValue;
        while(true) {
            // 获取共享变量旧值,可以在这一行加入断点,修改 data 调试来加深理解
            oldValue = data;
            // cas 尝试修改 data 为旧值 + amount,如果期间旧值被别的线程改了,返回 false
            if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue-amount)) {
                return;     
            }     
        }  
    }
    public int getData() {
        returndata;  
    }
}

Account.demo(newAccount() {
    AtomicData atomicData = newAtomicData(10000);
    @Override
    public IntegergetBalance() {
        return atomicData.getData();
    }
    @Override 
    public void withdraw(Integeramount) {
        atomicData.decrease(amount);  
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值