当前位置:网站首页>Multithreading tutorial (XXVIII) unsafe class

Multithreading tutorial (XXVIII) unsafe class

2022-06-11 05:29:00 Have you become a great God today

Multithreading tutorial ( Twenty-eight )unsafe class

Unsafe Object provides a very low-level , Operating memory 、 Thread method ,Unsafe Object cannot be called directly , Only by reflection

public class UnsafeAccessor {
    
    static Unsafe unsafe;
    static {
    
        try {
     
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
    
            throw new Error(e);
        }
    }
    static Unsafe getUnsafe() {
    
        return unsafe;
    }
}

1.Unsafe CAS operation

@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");
//  Get the offset of the member variable 
long idOffset = UnsafeAccessor.unsafe.objectFieldOffset(id);
long nameOffset = UnsafeAccessor.unsafe.objectFieldOffset(name);
Student student = new Student();
//  Use  cas  Method to replace the value of a member variable 
UnsafeAccessor.unsafe.compareAndSwapInt(student, idOffset, 0, 20); //  return  true
UnsafeAccessor.unsafe.compareAndSwapObject(student, nameOffset, null, " Zhang San "); //  return  true
System.out.println(student);

Output

Student(id=20, name= Zhang San )

Use custom AtomicData Thread safe atomic integers before implementation Account Realization

class AtomicData {
    
    private volatile int data;
    static final Unsafe unsafe;
    static final long DATA_OFFSET;
    static {
    
        unsafe = UnsafeAccessor.getUnsafe();
        try {
    
            // data  Attribute in  DataContainer  Offset in object , be used for  Unsafe  Access the property directly 
            DATA_OFFSET = unsafe.objectFieldOffset(AtomicData.class.getDeclaredField("data"));
        } catch (NoSuchFieldException e) {
    
            throw new Error(e);
        }
    }
    public AtomicData(int data) {
    
        this.data = data;
    }
    public void decrease(int amount) {
    
        int oldValue;
        while(true) {
    
            //  Get the old value of the shared variable , You can add breakpoints to this line , modify  data  Debug to deepen understanding 
            oldValue = data;
            // cas  Try to modify  data  by   The old value  + amount, If the old value is changed by another thread , return  false
            if (unsafe.compareAndSwapInt(this, DATA_OFFSET, oldValue, oldValue - amount)) {
    
                return;
            }
        }
    }
    public int getData() {
    
        return data;
    }
}

Account Realization

Account.demo(new Account() {
    
    AtomicData atomicData = new AtomicData(10000);
    @Override
    public Integer getBalance() {
    
        return atomicData.getData();
    }
    @Override
    public void withdraw(Integer amount) {
    
        atomicData.decrease(amount);
    }
});
原网站

版权声明
本文为[Have you become a great God today]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020539055625.html