Java中的锁机制——自旋锁

目录

自旋锁(spinlock)

自定义一个自旋锁


 

自旋锁(spinlock)

 

自旋锁指尝试获取锁的线程获取不到不会立即阻塞,而是采用循环的方式去尝试获取锁

这样做的好处是减少了线程频繁切换引起的性能损耗,但缺点是会增加cpu占用资源的时间。

自旋锁1.6以后默认开启,自旋次数默认是10次,它会记录上次是多久自旋后成功

我们在cas遇见过自旋锁,回顾下。CAS使用了“自旋锁+赋新值”的方式实现了比较并交换

在自旋锁的第一行代码中有var5=xxx,这是为了当第一次比较失败时,让期望值获取最新主存的值。

比较期望值和主存值的目的是为了每次工作线程把新值写给主存时,新值都是用最新的主存值计算而来的

Java中的锁机制——自旋锁_第1张图片

 

 

自定义一个自旋锁

 

这个例子不难看懂,AB两个人同时进入了厕所,但现在只有一个坑位。A要进坑,得锁门,B需要在门外等待~

这里走了一个while自旋锁,A不会进入到自旋锁中,B会进入到自旋锁。你理解了吗?

public class SpinLockDemo {

    //原子引用线程
    AtomicReference atomicReference = new AtomicReference<>();

    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName() + "\t come in!");
        //坑里有人
        while (!atomicReference.compareAndSet(null, thread)){

        }
    }

    public void myUnlock(){
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread, null);
        System.out.println(Thread.currentThread().getName() + "\t invoked myUnLock()");
    }

    public static void main(String[] args) {
        SpinLockDemo spinLockDemo = new SpinLockDemo();
        new Thread(()->{
            spinLockDemo.myLock();
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            spinLockDemo.myUnlock();
        }, "AA").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            spinLockDemo.myLock();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            spinLockDemo.myUnlock();
        }, "BB").start();

    }
}

最后AA myUnLock代表A完事释放坑,把门锁打开。此时BB可以进坑了,B完事又执行myUnLock开门

Java中的锁机制——自旋锁_第2张图片

 

你可能感兴趣的:([线程与并发])