公平锁/非公平锁/可重入锁/自旋锁

news2024/11/26 0:40:09

在JAVA中我们知道有很多加锁的方式,比如常见的 通过synchronized关键字,还有Lock,还有之前说原子CAS操作时有看到过的死循环方式的自旋锁。

借此来说一下锁的分类:

公平锁:

是指多个线程按照申请的顺序来获取锁,每次获取锁时会先查看此锁维护的等待队列。先到先得。

非公平锁:

是指多个线程获取锁的顺序并不是按照申请锁的顺序,每个线程不停的去获取锁,直到成功,有可能后申请的线程比先申请的线程更先获取锁,高并发情况下,有可能造成优先级反转或者饥饿现象。

常见的非公平锁 synchronized/ReentrantLock(默认创建非公平锁new ReentrangLock(false/true))

不填默认就是false也可以 填写true使他变为公平锁。

可重入锁(递归锁):

synchronized/ReentrantLock都是可重入锁

线程可以进入任何一个他已经拥有的锁所同步着的代码块。

指的是同一线程外层函数获得锁之后,在进入内层方法会自动获取锁。可避免死锁

public synchronized method1(){
	method2();
}
public synchronized method2(){

}

复制

像这样的代码就表示了一个可重入锁。获取了method1方法的锁之后调用method2会自动获取锁。

看以下代码来确定以下是否是这样的。

这里我创建了两个线程A和B,每个线程调用method1方法,method1又调用了method2方法,method1和method2都加了锁,那么我们看一下运行结果,他们打印的线程名称是不是都是同一线程名。

可以看到结果在进入method2后获取锁的线程依然还是method1获取锁的那个线程,这就是可重入锁的表现。当然用上方代码块synchronized加锁的方式也可以达到可重入锁的效果,小伙伴们可以试一下。

自旋锁(spinlock):

是指尝试获取锁的线程不会立即进行阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少了线程之间的上下文切换消耗,缺点是循环会消耗CPU性能。

之前在说CAS操作时有提到过比较且交换这个点。那我们就根据他所提供的方法来自己写一个自旋锁,借此来复习一下之前的原子类操作知识点。

public class SpinLockDemo {
    /**
     * 之前有提到过AtomicReference这个原子类,它可以原子操作任何其他类,这里我们泛型里边写个Thread类
     * */
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void getLock() {
        // 获取当前执行此方法的线程
        Thread thread = Thread.currentThread();

        // 如果当前atomicReference内部值为null 则上锁,否则进入循环不停判断
        while (!atomicReference.compareAndSet(null, thread)) {
//            System.out.println("线程: " + thread.getName() + "尝试获取锁");
        }
        System.out.println("线程:\t" + thread.getName() + "\t进行加锁");
    }

    public void getUnLock() {
        // 获取当前执行此方法的线程
        Thread thread = Thread.currentThread();

        // 比较且将atomicReference内部值赋为null
        atomicReference.compareAndSet(thread, null);
        System.out.println("线程:\t" + thread.getName() + "释放了锁");
    }

    public static void main(String[] args) {

        SpinLockDemo spinLockDemo = new SpinLockDemo();

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

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

            spinLockDemo.getUnLock();
        },"A").start();

        new Thread(() -> {
            spinLockDemo.getLock();
            spinLockDemo.getUnLock();
        },"B").start();


    }
}

复制

上边线程A先执行肯定先获取到了锁,然后休息3秒钟,咱们看执行结果是不是线程B在A释放锁之后

才能进行加锁。

我们可以看到线程B在A释放之后才成功的获取到了锁。

以上就是通过CAS原子操作实现的一个CAS自旋锁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/643930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dp算法篇Day1

"多希望有人来陪我&#xff0c;度过末日啊~" 讲讲我为什么突然想更新这篇栏目。 想想自己也算 "系统" 接触计算机这个学科也有差不多一年了&#xff0c;回想起当初下定决心要全身心投入到这个专业或者说行业中来&#xff0c;现在到了这样的地步&#xff0c…

CSS基础学习--10 margin(外边距)

一、定义&#xff1a; CSS margin(外边距)属性定义元素周围的空间。 二、margin margin 清除周围的&#xff08;外边框&#xff09;元素区域。margin 没有背景颜色&#xff0c;是完全透明的。 margin 可以单独改变元素的上&#xff0c;下&#xff0c;左&#xff0c;右边距&a…

今天面了个35k字节跳动出来,真是砂纸擦屁股,给我露了一手...

​2023年春招已经结束&#xff0c;很多小伙伴收获不错&#xff0c;拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文&#xff0c;为此咱这里也统一做一次大整理和大归类&#xff0c;这也算是划重点了。 俗话说得好&#xff0c;他山之石…

AI 绘画(0):导论

文章目录 导论感谢人员Ai绘画前期准备软件环境硬件条件 Ai绘画介绍Ai绘画简单流程介绍Ai绘画软件介绍参数输入介绍 Ai绘画公约 导论 Ai绘画是最近比较热门的绘画方式&#xff0c;以干掉原画师为口号&#xff0c;引起了激烈的讨论。Ai绘画能否取代人工我们先不谈&#xff0c;但…

一个专科生的 Python 转行之路

自学之路 正式开始学编程是在十月底的样子, 那时候在知乎 flask 话题下看到一个问题 「有多少人按萧井陌大神给出的PythonFlask路线找到工作了&#xff1f;」。就觉得自己也可以啊, 就开始辞职自学 Python,。 刚开始的那一个月确实能够做到每天 10 个小时写代码, 学了大概一个…

java设计模式之:外观模式

前言 举个现实生活中例子&#xff0c;泡茶和去茶馆喝茶的区别&#xff0c;如果是自己泡茶需要自行准备茶叶、茶具和开水&#xff0c;而去茶馆喝茶&#xff0c;最简单的方式就是跟茶馆服务员说想要一杯什么样的茶&#xff0c;是铁观音、碧螺春还是西湖龙井&#xff1f;正因为茶…

互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景

多线程访问共享资源的时候&#xff0c;避免不了资源竞争而导致数据错乱的问题&#xff0c;所以我们通常为了解决这一问题&#xff0c;都会在访问共享资源之前加锁。 最常用的就是互斥锁&#xff0c;当然还有很多种不同的锁&#xff0c;比如自旋锁、读写锁、乐观锁等&#xff0…

数据结构——树和二叉树

文章目录 **一 数的基本概念****1 定义****2 基本术语****3 树的性质** **二 二叉树的概念****1 二叉树的定义和特性****1.1 定义****1.2 特殊的二叉树****1.3 二叉树的性质** **2 二叉树的存储结构****2.1 顺序存储结构****2.2 链式存储结构** **三 二叉树的遍历和线索二叉树*…

Spark SQL数据源的基本操作(更新ing)

文章目录 一、基本操作二、默认数据源&#xff08;一&#xff09;默认数据源Parquet&#xff08;二&#xff09;案例演示读取Parquet文件1、在Spark Shell中演示练习1、将student.txt文件转换成student.parquet练习2、读取student.parquet文件得到学生数据帧&#xff0c;并显示…

K8S minikube本地安装

一. mac安装K8S 1.brew安装 brew install kubectl 2.查看版本 kubectl version --outputjson { "clientVersion": { "major": "1", "minor": "27", "gitVersion": "v1.27.2", &…

基于深度学习的高精度奶牛检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度奶牛检测识别系统可用于日常生活中或野外来检测与定位奶牛目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的奶牛目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

locked勒索病毒利用零日漏洞,企业服务器数据瞬间遭受致命加密

目录 引言&#xff1a; 事件概述&#xff1a; .locked勒索病毒加密算法&#xff1a; 数据恢复建议&#xff1a; locked勒索病毒数据恢复案例&#xff1a; 什么叫零日漏洞&#xff1f; 对策建议&#xff1a; 引言&#xff1a; 近日&#xff0c;网络安全界再次爆发了一起…

RK3588平台开发系列讲解(系统篇)开机启动原因

文章目录 一、系统开机启动原因二、开机启动场景沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解平台系统开机启动原因介绍。 一、系统开机启动原因 开机原因记录文件在/proc/sys/kernel/boot_reason,那么开机后可以从这个文件中读取数值来获知本次开机…

锁升级:无锁、偏向锁、轻量级锁、重量级锁

锁升级 JDK 1.6之前&#xff0c;synchronized 还是一个重量级锁&#xff0c;是一个效率比较低下的锁。但是在JDK 1.6后&#xff0c;JVM为了提高锁的获取与释放效率对synchronized 进行了优化&#xff0c;引入了偏向锁和轻量级锁 &#xff0c;从此以后锁的状态就有了四种&#…

开源SCRM营销平台MarketGo-数据管理

一、概述 企业在私域运营的场景下&#xff0c;系统在运行中会产生一些用户数据和行为数据。 用户数据包含年龄&#xff0c;性别&#xff0c;生日&#xff0c;电话&#xff0c;用户标签&#xff0c;还有用户和员工的关系等信息。行为数据包含在SCRM中创建活动的用户事件&#…

自学黑客(网络安全)?一般人我劝你还是算了吧!

前言 博主本人 18年就读于一所普通的本科学校&#xff0c;21年 6 月在三年经验的时候顺利通过校招实习面试进入大厂&#xff0c;现就职于某大厂安全联合实验室。 我为啥说自学黑客&#xff08;网络安全&#xff09;&#xff0c;一般人我还是劝你算了吧。因为我就是那个不一般的…

【C++】c++11的新特性——右值引用/移动语义/lambda表达式

文章目录 C11介绍1. 统一的列表初始化1.1 {}初始化1.2 std::initializer_list 2. 一些关键字2.1 auto2.2 decltype2.3 nullptr 3. 范围for4. 右值引用和移动语义&#xff08;重点&#xff09;4.1 左值引用和右值引用4.2 右值引用的应用4.3 总结 5. 万能引用和完美转发6. 新的类…

mysql小表驱动大表

摘要&#xff1a; 小表驱动大表为了减少匹配时的数据量 判断谁做小表时&#xff0c;是比较算上过滤条件后的数量 left join时手动设置小表驱动大表 inner join时优化器会自动小表驱动大表 course–100条数据 student_info–100w条数据 优化器会选择小表驱动大表&#xff08;这里…

使用VMware Workstation一步一步安装Rocky Linux 9

目录 目录 背景 准备阶段 新建虚拟机 安装Rocky Linux 进入系统 背景 Rocky Linux 简介 企业Linux&#xff0c;社区方式。 Rocky Linux是一个开源的企业操作系统&#xff0c;旨在与红帽企业Linux100%兼容。社区正在大力发展。 Rocky Linux 9.2 于2023年5月16日发布&a…

计算机组成原理(六)指令系统

一、指令的基本格式 1.1机器指令的相关概念 指令集(Instruction Set) 某机器所有机器指令的集合 *定长指令集 指令集中的所有指令长度均相同!取指令控制简单*不定长指令集 指令集中的所有指令长度有长、有短 操作码 (1)长度固定 用于指令字长较长的情况RISC 如IBM370操作码8位…