锁策略和CAS指令

news2024/9/22 1:24:44

锁策略

  • 一、锁策略的引入
  • 二、锁策略的分类
    • (1)乐观锁和悲观锁
    • (2)重量级锁和轻量级锁
    • (3) 自旋锁和挂起等待锁
    • (4)可重入锁和不可重入锁
    • (5)公平锁和非公平锁
    • (6)互斥锁和读写锁
    • synchronized 实现原理
      • 锁的自适应
  • 三、锁消除
  • 锁粗化
  • CAS指令
  • 总结


一、锁策略的引入

锁策略的使用表示当锁遇到加锁/解锁/锁冲突/的时候所采取的方法。

二、锁策略的分类

(1)乐观锁和悲观锁

加锁的时候,预测当前锁冲突的概率大小。
预测冲突概率大,那么后续要做的工作就会增加,加锁开销所花费的资源开销就更大。(悲观锁)
预测冲突概率小,那么后续要做的工作就会减少,加锁开销所花费的资源开销就更小。(乐观锁)
synchronized既是乐观锁,也是悲观锁。它支持自适应,能够自动统计当前锁冲突的次数,进行判定当前锁冲突的概率大小。当冲突概率低,就采取乐观锁执行,当冲突概率高,则会自动上升为悲观锁执行。

在悲观锁中,往往需要内核态和用户态共同完成一些操作,要做的工作就比较多;而在乐观锁中,采取的是纯用户态进行执行,要做的工作就比较少。

(2)重量级锁和轻量级锁

这两种锁,顾名思义,根据所需要进行的工作,所要花费的资源来区分锁是否重量。 一般来说,悲观锁就是重量级锁,乐观锁就是轻量级锁。

(3) 自旋锁和挂起等待锁

自旋锁是轻量级锁的一种典型实现方式。
所谓自旋,即cpu处于空转、忙等状态,消耗了很多cpu资源。但是一旦锁被释放,那么自旋锁就能第一时间拿到锁。即通过消耗cpu资源的方式,提高了获取锁的速度。
挂起等待锁是重量级锁的一种典型实现方式。
在该类锁中,当尝试加锁时,锁被占用的状态下,就会让尝试加锁的该线程进入挂起(阻塞)状态,此时该线程不会参与调度。直到该锁被释放之后,系统会重新唤醒该线程,重新参与锁竞争获取锁。
synchronized轻量级锁部分,是基于自旋锁实现;重量级锁部分,是基于挂起等待锁实现。

(4)可重入锁和不可重入锁

synchronized属于可重入锁,即在一个线程中,连续加同一把锁两次不会发生死锁。
相反,不可重入锁即一个线程中针对同一把锁连续加锁两次,会发生死锁。

(5)公平锁和非公平锁

公平锁:严格按照先来后到的顺序获取锁,即哪个线程等待的时间长,哪个就先拿到锁。
非公平锁:若干个线程进行锁竞争。
synchronized属于非公平锁。

(6)互斥锁和读写锁

互斥锁:synchronized 属于普通的互斥锁,只有普通的加锁和解锁。

读写锁:在该锁中,读操作和写操作之间是互斥的,有利于降低锁冲突的概率,提高并发能力。其中有以下三个特点


  1. 读锁和读锁之间,不会产生互斥。
  2. 读锁和写锁之间,会产生互斥。
  3. 写锁和写锁之间,会产生互斥。

synchronized 实现原理

synchronized既是悲观锁,也是乐观锁;既是轻量级锁,也是重量级锁;轻量级锁是自旋锁实现,重量级锁是挂起等待锁实现。

锁的自适应

synchronized拥有自适应的功能,会根据不同的情况进行升级。这个升级过程分为四步。

  1. 未加锁的状态
  2. 当调用synchronzied的时候,就会尝试加锁,这时叫做偏向锁,即“似锁非锁“,处于不锁和锁之间的中间态。当不需要锁的时候,就不加锁;当遇到锁冲突的时候,马上加锁升级为轻量级锁。
  3. 轻量级锁是最初步的锁,所需要的工作较少。
  4. 当冲突进一步提升,锁升级为重量级锁。
  5. 在上述的锁升级过程中,锁不能降级只能升级。

三、锁消除

锁消除是编译器的优化策略。在进行加锁操作后,编译器会对当前代码进行判定,判断这个地方到底需不需要锁,如果不需要就优化掉加锁操作。

锁粗化

锁粗化也属于一种优化策略。在部分逻辑中,需要频繁的加锁解锁。编译器会自动将多个细粒度的锁合并成一次粗粒度的锁。
伪代码如下图所示
在这里插入图片描述

CAS指令

CAS(compare and swap) 属于一条cpu原子指令,负责完成比较和交换操作。
在JVM中对CAS指令进行封装,以便Java代码中可以使用CAS操作。承载CAS指令的载体之一就是**原子类(Atomic) **。
以子类AtomicInteger进行解释,对int进行封装,此时无论是++还是–等一系列操作都是原子的。这也保证了线程安全的操作。
下面为代码案例

public static void main(String[] args) {
        //原子类
        AtomicInteger count = new AtomicInteger(0);
        //count++
        count.getAndIncrement();
        //++count
        count.incrementAndGet();
        //count--
        count.getAndDecrement();
        //--count
        count.decrementAndGet();
        //count += 10
        count.getAndAdd(10);
        System.out.println(count);
    }

注意事项:在CAS中,通过比较 发现相等之后进行交换,但是相等并不等于没有交换过。或许在这个指令执行之前,数据改变过又改变回来了。

总结

原子类源码 ☞原子类代码

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

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

相关文章

SQL面试题练习 —— 统计最大连续登录天数区间

目录 1 题目2 建表语句3 题解 1 题目 2 建表语句 CREATE TABLE IF NOT EXISTS user_login_tb (uid INT,login_date DATE ); insert into user_login_tb(uid, login_date) values( 1, 2022-08-02),(1, 2022-08-03),(2, 2022-08-03),(2, 2022-08-04),(2, 2022-08-05),(2, 2022-08…

使用Python的Turtle模块绘制小黄人

引言 在Python编程的世界里,turtle 模块是一个非常有趣且实用的工具,它允许程序员通过简单的指令控制一个虚拟的画笔(称为“海龟”)在屏幕上移动和绘制图形。本篇博客将详细介绍如何使用turtle模块来绘制一个卡通人物&#xff0c…

Redis-布隆过滤器(Bloom Filter)详解

文章目录 什么是布隆过滤器 布隆过滤器的优点:布隆过滤器的缺点:其他问题 布隆过滤器适合的场景布隆过滤器原理 数据结构增加元素查询元素删除元素 如何使用布隆过滤器 Google开源的Guava自带布隆过滤器Redis实现布隆过滤器 Redis中配置布隆过滤器Redis…

给Wordpress添加评分功能到评论表单

今天要 给你的 Wordpress 添加评分功能到评论表单 吗? 评分功能效果图 什么类型的网站需要评分? 资源站教程站其他,我也没想到。。。 但我这个网站,因为是电影类的网站,好像还是有点需要的,所以&#xf…

完美的用户体验:如何设计一个直观和有效的网站导航?

APP的顶部导航栏对我们来说很熟悉。导航栏是UI设计中不可或缺的一部分,几乎每个页面都使用导航栏。虽然导航栏看起来很简单,不需要太多精力,但是设计一个与产品需求和客户目标高度匹配的导航栏并不是那么容易的。导航栏的设计标准有很多细节需…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址:源码地址 一、什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe&…

C++ : 移除链表元素/合并两个有序链表题解

目录 1.移除链表元素 分析 代码 2.合并两个有序链表 分析 代码 1.移除链表元素 分析 像这种移除元素的,加个哨兵位头节点会比较方便,因为旧的头会有被移除的情况,不好控制。这里只需要用cur指向待遍历的节点,prev指向cur的…

AI大牛Karpathy创办Eureka Labs专注AI+教育

🦉 AI新闻 🚀 AI大牛Karpathy创办Eureka Labs专注AI教育 摘要:前OpenAI大牛Karpathy离职半年后宣布创办专注AI与教育的公司Eureka Labs,旨在通过生成式AI优化教育体验。公司首个项目LLM101n课程已在GitHub获得高赞,目…

C++ 继承详解:从基础到深入

继承是面向对象编程中最强大的功能之一,它不仅促进了代码的重用,还帮助我们构建复杂的系统。在C中,通过继承,我们可以创建一个新的类(称为派生类)来扩展现有类(基类)的功能。本文将全…

基于python的百度资讯爬虫的设计与实现

研究背景 随着互联网和信息技术的飞速发展,网络已经成为人们获取信息的主要来源之一。特别是搜索引擎,作为信息检索的核心工具,极大地改变了人们获取信息的方式。其中,百度作为中国最受欢迎的搜索引擎之一,其新闻搜索…

[GXYCTF2019]Ping Ping Ping1

打开靶机 结合题目名称,考虑是命令注入,试试ls 结果应该就在flag.php。尝试构造命令注入载荷。 cat flag.php 可以看到过滤了空格,用 $IFS$1替换空格 还过滤了flag,我们用字符拼接的方式看能否绕过,ag;cat$IFS$1fla$a.php。注意这里用分号间隔…

【总结】逻辑运算在Z3中运用+CTF习题

国际赛IrisCTF在前几天举办,遇到了一道有意思的题目,特来总结。 题目 附件如下:📎babyrevjohnson.tar 解题过程 关键main函数分析如下: int __fastcall main(int argc, const char **argv, const char**envp){int v4…

Golang | Leetcode Golang题解之第236题二叉树的最近公共祖先

题目: 题解: func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {parent : map[int]*TreeNode{}visited : map[int]bool{}var dfs func(*TreeNode)dfs func(r *TreeNode) {if r nil {return}if r.Left ! nil {parent[r.Left.Val] rdfs(r.L…

用 WireShark 抓住 TCP

Wireshark 是帮助我们分析网络请求的利器,建议每个同学都装一个。我们先用 Wireshark 抓取一个完整的连接建立、发送数据、断开连接的过程。 简单的介绍一下操作流程。 1、首先打开 Wireshark,在欢迎界面会列出当前机器上的所有网口、虚机网口等可以抓取…

气膜体育馆进校园:政策支持与市场前景—轻空间

过去20多年,气膜建筑、场馆相关项目在国内落地众多,展现出强大的市场潜力。2022年8月,《北京晚报》粗略统计,北京全市已建有气膜馆百余座,且数量还在不断增加。这一发展趋势不仅仅体现在北京,全国范围内也都…

微软GraphRAG +本地模型+Gradio 简单测试笔记

安装 pip install graphragmkdir -p ./ragtest/input#将文档拷贝至 ./ragtest/input/ 下python -m graphrag.index --init --root ./ragtest修改settings.yaml encoding_model: cl100k_base skip_workflows: [] llm:api_key: ${GRAPHRAG_API_KEY}type: openai_chat # or azu…

如何通过企业微信会话存档保护企业利益?

赵总: 张经理,最近行业内频发数据泄露事件,我们的客户资料和内部沟通记录安全吗? 张经理: 赵总,我们已经采取了一系列措施来加强数据安全。特别是针对企业微信的沟通记录,我们最近引入了安企神软件,它能很…

【BUG】已解决:AttributeError: ‘NoneType‘ object has no attribute ‘split‘

已解决:AttributeError: ‘NoneType‘ object has no attribute ‘split‘ 英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,…

通用图形处理器设计GPGPU基础与架构(四)

一、前言 本文将介绍GPGPU中线程束的调度方案、记分牌方案和线程块的分配与调度方案。 二、线程束调度 在计算机中有很多资源,既可以是虚拟的计算资源,如线程、进程或数据流,也可以是硬件资源,如处理器、网络连接或 ALU 单元。调…

大数据平台之Kafka

Apache Kafka 是一个分布式流处理平台,最初由 LinkedIn 开发,并在 2011 年开源成为 Apache 项目。Kafka 主要用于构建实时数据管道和流应用,具有高吞吐量、低延迟、容错性强等特点。以下是对 Kafka 的详细介绍: 核心概念 1. Prod…