CAS和Unsafe

Posted z啵唧啵唧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS和Unsafe相关的知识,希望对你有一定的参考价值。

五、CAS

CAS实现锁的原理

@Slf4j(topic = "c.LockCas")
public class LockCas 

    /**
     * 0表示没有加锁
     * 1表示加锁
     */
    private AtomicInteger state = new AtomicInteger(0);

    public void lock() 
        //实际上在这个地方会存在空运转的问题
        while (true) 
            //cas操作,采用了cas的原理实现
            if (state.compareAndSet(0, 1)) 
                break;
            
        
    

    public void unlock() 
        log.debug("unlock...");
        //解锁将state的值设置为0即可
        state.set(0);
    

    public static void main(String[] args) 
        LockCas lock;
        lock = new LockCas();
        new Thread(() -> 
            log.debug("begin...");
            lock.lock();
            try 
                log.debug("lock...");
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
             finally 
                lock.unlock();
            
        ).start();
        new Thread(() -> 
            log.debug("begin...");
            //线程二去调用lock方法的时候发现修改不了,因为线程1先一步调用了lock方法并且将state的值改成了1
            //此时线程2只能等线程1睡眠时间过后调用了unlock方法将state的值改为了0,才能此时线程2才能调用lock方法进行加锁
            lock.lock();
            try 
                log.debug("lock...");

             finally 
                lock.unlock();
            
        ).start();
    

Unsafe类

  • Unsafe对象提供了非常底层,操作内存,线程的方法,Unsafe对象不能直接调用,只能通过反射获得
  • 如AtomicInteger底层的一些方法实际上就是调用的就是unsafe类的一些方法
  • LockSupport类底层的park、unpark调用的也是unsafe对象的方法
unsafe对象的获取
public class TestUnsafe 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException 
        //获得unsafe对象
        //获得unsafe成员变量
        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        //设置允许访问私有变量
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe)theUnsafe.get(null);
        //打印查看是否成功获得
        System.out.println(unsafe);
    

unsafe CAS操作
public class TestUnsafe 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException 
        //获得unsafe对象
        //获得unsafe成员变量
        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        //设置允许访问私有变量
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe)theUnsafe.get(null);

        //1、获取域的偏移地址
         long idOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
         long nameOffset = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));

         Teacher t = new Teacher();
        //2、执行cas操作

        unsafe.compareAndSwapInt(t,idOffset,0,1);
        unsafe.compareAndSwapObject(t,nameOffset,null,"张三");

        //3、验证
        System.out.println(t);
    

@Data
class Teacher
    volatile int id;
    volatile String name;

以上是关于CAS和Unsafe的主要内容,如果未能解决你的问题,请参考以下文章

UnSafe类中的CAS操作

Unsafe与CAS

自己利用unsafe的cas实现的AtomicInteger

Java并发:CAS Unsafe Atomic

通过 UNSAFE 来实现一个 Atomic 的 CAS 辅助类原创

javajava 使用 Unsafe CAS 实现数据递增 打印重复问题