Java基础知识-自旋锁

  • Post author:
  • Post category:java




一、自旋锁是什么?


自旋锁(Spin Lock)是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。



二、代码实现



手写自旋锁


代码如下:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class SpinLockDome {

    AtomicReference<Thread> atomic = new AtomicReference<>();

    public  void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println("thread = " + thread.getName()+" \t come in !(>^ω^<)喵");
        while (!atomic.compareAndSet(null,thread)){}
    }
    
    public void myUnLock(){
        Thread thread =Thread.currentThread();
        atomic.compareAndSet(thread,null);
        System.out.println("thread = " + thread.getName()+" \t come out !(>^ω^<)喵");
    }


    public static void main(String[] args) {
        SpinLockDome s = new SpinLockDome();
        new Thread(()->{
            s.myLock();
            try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {}
            s.myUnLock();
        },"A").start();

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

        new Thread(()->{
            s.myLock();
            s.myUnLock();
        },"B").start();
    }
}


输出结果如下:

thread = A 	 come in !(>^ω^<)喵
thread = B 	 come in !(>^ω^<)喵
thread = A 	 come out !(>^ω^<)喵
thread = B 	 come out !(>^ω^<)喵

Process finished with exit code 0



三、总结


提到了互斥同步对性能最大的影响阻塞的实现,挂起线程和恢复线程的操作都需要转入内核态完成,这些操作给系统的并发性能带来了很大的压力。同时,虚拟机的开发团队也注意到在许多应用上,共享数据的锁定状态只会持续很短的一段时间,为了这段时间去挂起和恢复线程并不值得。如果物理机器有一个以上的处理器,能让两个或以上的线程同时并行执行,我们就可以让后面请求锁的那个线程 “稍等一下”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只需让线程执行一个忙循环(自旋),这项技术就是所谓的自旋锁。



版权声明:本文为weixin_39505814原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。