什么是自旋锁,代码演示

自旋锁是一种同步机制,用于多线程环境,当锁被占用时,线程会持续循环尝试获取,不释放CPU时间片。相比之下,互斥锁在未获取锁时会让线程进入休眠状态。在多核系统中,如果任务执行快速,自旋锁更有效;而在单核系统或长时间持有锁的情况下,互斥锁更为合适。文章提供了一个Java实现自旋锁的示例,通过AtomicReference实现线程安全的锁机制。

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

01 自旋锁(spinlock)

过程
获取锁
访问共享资源
释放锁

自旋锁
循环尝试获取锁,不会放弃CPU时间片,减伤cup上下文切换,缺点是循环会消耗cpu
非自旋锁
如果获取不到锁,让线程休眠,CPU就可以在这段时间去做很多其他的事情,直到之前持有这把锁的线程释放了锁,于是CPU再把之前的线程恢复回来,让这个线程再去尝试获取这把锁。若再次失败,就再次让线程休眠,若成功,一样可以成功获取到同步资源的锁

在这里插入图片描述

如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即获取锁。
如果在获取锁时已经有持有者,那么锁操作将自旋,直到自旋锁的保持者释放了锁。

缺点
自旋锁一直占用着CPU,他在未获得锁的情况下,一直运行(自旋),所以占用着CPU,如果不能在很短的时间内获得锁,这无疑会使CPU效率降低

互斥锁与自旋锁区别

    互斥锁  在未获得锁时,cup会进行切换,不会一直等待
    自旋锁   在未获得锁时,一直占用着CPU,一直运行(自旋)抢占CUP

 在多核机器中,如果锁住的“事务”很简单,占用很少时间,应该用自旋锁,自旋锁代价比互斥锁会小很多。”事务”很快执行完毕,自旋的消耗远远小于陷入sleep和wake的消耗。如果锁住“事务”粒度较大,就应该使用互斥锁,因为如果用自旋锁,那么在“事务”执行过程中自旋很长时间还不如使得线程sleep
 在单核机器中。自旋锁没有任何意义的,自旋锁只会浪费唯一核心的cpu 时间片,这个时刻没有任何线程会运行的。所以单核机器中,不论锁住的”事务”的粒度大小都要使用。

手写自旋

public class SpinLockDemo {
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"\t"+"----come in");
        // 因为atomicReference没有set,所以是null,compareAndSet方法比较如果是null,就修改为当前线程,如果不是null,就循环判断
        while (!atomicReference.compareAndSet(null, thread)) {
        }
    }

    public void unLock() {
        Thread thread = Thread.currentThread();
        // 如果atomicReference存储的是当前线程,就修改为null
        atomicReference.compareAndSet(thread,null);
        System.out.println(Thread.currentThread().getName()+"\t"+"----task over,unLock...");
    }

    public static void main(String[] args) {
        SpinLockDemo spinLockDemo = new SpinLockDemo();

        new Thread(() -> {
            spinLockDemo.lock();
            // 业务逻辑
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            spinLockDemo.unLock();
        },"A").start();

        // 暂停500毫秒,线程A先于B启动
        try { TimeUnit.MILLISECONDS.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }

        new Thread(() -> {
            spinLockDemo.lock();

            spinLockDemo.unLock();
        },"B").start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值