Java中的自旋锁spinlock详解

 更新时间:2024年01月13日 10:12:46   作者:java架构师-太阳  
这篇文章主要介绍了Java中的自旋锁spinlock详解,自旋锁就是循环尝试获取锁,不会放弃CPU时间片,减伤cup上下文切换,缺点是循环会消耗cpu,需要的朋友可以参考下

自旋锁

过程

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

自旋锁

循环尝试获取锁,不会放弃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();
    }
}

到此这篇关于Java中的自旋锁spinlock详解的文章就介绍到这了,更多相关自旋锁spinlock内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Eclipse使用maven搭建spring mvc图文教程

    Eclipse使用maven搭建spring mvc图文教程

    这篇文章主要为大家分享了Eclipse使用maven搭建spring mvc图文教程,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Java中ArrayList和Vector的区别

    Java中ArrayList和Vector的区别

    本文主要介绍了Java中ArrayList和Vector的区别,包括线程安全性、性能、同步机制、扩容机制、遍历方式等,具有一定的参考价值,感兴趣的可以了解一下
    2024-11-11
  • SpringBoot在一定时间内限制接口请求次数的实现示例

    SpringBoot在一定时间内限制接口请求次数的实现示例

    在项目中,接口的暴露在外面,很多人就会恶意多次快速请求,本文主要介绍了SpringBoot在一定时间内限制接口请求次数的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2022-03-03
  • Java中大数据推荐算法使用场景分析

    Java中大数据推荐算法使用场景分析

    在Java中实现大数据推荐算法时,通常会使用一些开源的机器学习库,如Apache Mahout、Weka、DL4J(DeepLearning4j,用于深度学习)或者Spark MLlib(用于在Spark集群上运行),这篇文章主要介绍了Java中可以用的大数据推荐算法,需要的朋友可以参考下
    2024-06-06
  • Spring IOC容器Bean管理的完全注解开发放弃配置文件

    Spring IOC容器Bean管理的完全注解开发放弃配置文件

    这篇文章主要为大家介绍了Spring IOC容器的Bean管理完全注解开发放弃配置文件,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • spring源码下载、编译、debug的详细教程

    spring源码下载、编译、debug的详细教程

    这篇文章主要介绍了spring源码下载、编译、debug的详细教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • java 中break如何跳出外部循环

    java 中break如何跳出外部循环

    这篇文章主要介绍了java 中break如何跳出外部循环,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java monitor机制使用方法解析

    Java monitor机制使用方法解析

    这篇文章主要介绍了Java monitor机制使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 利用Java的Struts框架实现电子邮件发送功能

    利用Java的Struts框架实现电子邮件发送功能

    这篇文章主要介绍了利用Java的Struts框架实现电子邮件发送功能,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-12-12
  • 图解如何在Spring Boot中使用JSP页面

    图解如何在Spring Boot中使用JSP页面

    这篇文章主要介绍了图解如何在Spring Boot中使用JSP页面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论