CAS和Unsafe

本文详细讲解了CAS(Compare and Swap)在LockCas类中的应用,展示了如何通过Unsafe类底层操作实现线程安全的加锁和解锁,并介绍了Unsafe对象的获取和cas操作实例。同时讨论了线程同步中空运转问题及Unsafe在Java并发中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

五、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;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值