CAS机制和synchronize的原理及其优化机制(锁消除 偏向锁 自旋锁 膨胀锁 锁粗化)

news2024/11/17 11:55:35

乐观锁的问题:并不总是能处理所有问题,所以会引入一定的系统复杂度。

读写锁

  • 把加锁操作分成了俩种 一是读锁二是写锁 也就是说在读和读之间是没有互斥的 但是在读写和写写之间就会存在互斥

  • 如果一个场景是一写多度 那么使用这个效率就会很高

重量级锁 VS 轻量级锁

  • 首先我们要知道加锁有一个很重要的特性就是保证原子性 原子性的功能其实来源于硬件(硬件提供了相关的原子操作的指令, 操作系统把这些指令统一封装成一个原子操作的接口, 应用程序才能使用这样的操作)

  • 所以在加锁过程中 如果整个加锁逻辑都是依赖于操作系统内核 那此时就是重量级锁(代码在内核中的开销会很大) 如果大多数操作都是用户自己完成的 少数由操作系统内核完成 这种就是轻量级锁

挂起等待锁 VS 自旋锁

  • 挂起等待锁表示当前获取锁失败后, 对应的线程就要在内核中挂起等待 (放弃CPU进入等待队列) 需要在锁对象释放之后由操作系统唤醒 (通常都是重量级锁)

  • 自旋锁表示当前获取锁失败后 不是立刻放弃CPU 而是快速频繁的再次访问锁的持有状态, 一旦锁对象被释放就能立刻获取到锁(通常都是轻量级锁)

自旋锁的效率更高, 但是会浪费一些CPU资源 (自旋相当于CPU在那空转)

公平锁 VS 非公平锁

  • 这种情况就是如果已经有多个线程在等待一把锁的释放 当释放之后, 恰好又来了一个新的线程也要获取锁

  • 公平锁: 保证之前先来的线程优先获取锁

  • 非公平锁: 新来的线程直接获取到锁, 之前的线程还得接着等待

实现公平锁就需要付出一些额外的代价 所以公平锁的效率是略低于非公平锁的

可重入锁

  • 一个线程针对同一把锁连续加锁俩次, 不会死锁, 这种就是可重入锁

可重入锁这就像是大门的三保险锁一样 我锁一层再锁一层 这种并不会造成我们死锁住自己 因为当我们想出去的时候又可以一层一层的开锁

死锁

  • 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

  • 我们常说的死锁有三个经典场景

  1. 一个线程一把锁 连续加锁俩次才 (保证使用的不是可重入锁)
  1. 俩个线程, 俩把锁, 相互获取对方的锁
  1. n个线程, n把锁, 哲学家就餐问题
  • 死锁产生的四个必要条件:(较为理论简单了解)

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

CAS

  • CAS的全称是 compare and swap(字面意思就是比较交换) 他是基于硬件提供的一种基础指令, 也是基于这样的指令, 就可以实现一些特殊的功能(实现锁)

  • 针对不同的操作系统,JVM 用到了不同的 CAS 实现原理

  • 简而言之,是因为硬件予以了支持,软件层面才能做到。

我们假设内存中的原数据val,旧的预期值new,需要修改的新值tmp。

  1. 比较 new 与 val 是否相等。(比较)
  1. 如果比较相等,将 tmp 写入 val。(交换)
  1. 返回操作是否成功。
  • 可见当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。可见 CAS 其实是一个乐观锁。

CAS的使用

在这里插入图片描述

上图所示就是使用的CAS封装了一些原子类如下面代码示例第一个使用CSA的锁第二个不使用 显然结果第一个是线程安全的第二个线程是不安全的

import java.util.concurrent.atomic.AtomicInteger;

/**

  • Created with IntelliJ IDEA.

  • Description: If you don’t work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-04

  • Time: 20:40

*/

public class Demo2 {

public static void main(String[] args) throws InterruptedException {

AtomicInteger atomicInteger = new AtomicInteger();

Thread thread = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

atomicInteger.addAndGet(1);

}

}

};

Thread thread1 = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

atomicInteger.addAndGet(1);

}

}

};

thread.start();

thread1.start();

thread.join();

thread1.join();

System.out.println(atomicInteger.get());

}

}

/**

  • Created with IntelliJ IDEA.

  • Description: If you don’t work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-04

  • Time: 20:53

*/

public class Demo3 {

private static int count = 0;

public static void main(String[] args) throws InterruptedException {

Thread thread = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

count++;

}

}

};

Thread thread1 = new Thread() {

@Override

public void run() {

for (int i = 0; i < 5000; i++) {

count++;

}

}

};

thread.start();

thread1.start();

thread.join();

thread1.join();

System.out.println(count);

}

}

CAS的缺陷 ABA问题

  • 这个问题就是加入现在有个num为0 有一个线程把他修改为1, 然后紧接着又有一个线程把他修改为0了 那此时仅仅通过CAS的比较是

无法区分的

  • 解决这个问题就需要引入额外的信息 (给变量加一个版本号 每次进行修改 都递增版本号)

synchronize的原理

  • synchronize是java中的关键字,可以用来修饰实例方法、静态方法、还有代码块;主要有三种作用:可以确保原子性、可见性、有序性,原子性就是能够保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等该线程处理完数据后才能进行;可见性就是当一个线程在修改共享数据时,其他线程能够看到,保证可见性,volatile关键字也有这个功能;有序性就是,被synchronize锁住后的线程相当于单线程,在单线程环境jvm的重排序是不会改变程序运行结果的,可以防止重排序对多线程的影响。

以synchronize为例学习锁优化

编辑器和JVM配合进行的

锁消除

  • 锁消除本质是以编辑器和JVM代码运行的情况智能的判断当前的锁有没有必要加 如果没有必要, 就会直接把锁干掉

/**

  • Created with IntelliJ IDEA.

  • Description: If you don’t work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-04

  • Time: 21:21

*/

public class Demo4 {

public static void main(String[] args) {

StringBuffer buffer = new StringBuffer();

buffer.append(“listen”);

buffer.append(“listen”);

buffer.append(“listen”);

buffer.append(“listen”);

System.out.println(buffer);

}

}

在这里插入图片描述

  • 到库中我们可以发现StringBuffer是加锁线程安全的 但是在我们上面写的代码中完全不用考虑线程安全问题 所以在实际运行的时候就把锁消除了

偏向锁

buffer.append(“listen”);

System.out.println(buffer);

}

}

在这里插入图片描述

  • 到库中我们可以发现StringBuffer是加锁线程安全的 但是在我们上面写的代码中完全不用考虑线程安全问题 所以在实际运行的时候就把锁消除了

偏向锁

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

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

相关文章

【数据结构与算法】B_树

目录 前言&#xff1a; 一、B树 1、B树概念 2、B树查找 3、B树插入 4、B树前序遍历 5、B树性能 二、B、B*树 1、B树概念 2、B树的插入 2、B*树概念 3、总结 三、B系列树的应用 总结 前言&#xff1a; 我们已经有很多索引的数据结构了 例如&#xff1a; 顺序查找 …

CAD外部参照文件的分解

最近遇到一个编图要求&#xff1a; “图纸文件的内容主要由模型空间和布局空间内的信息组成&#xff0c;尽量减少外部参照的使用。” 我们的综合图分幅主要依照外部参照来的&#xff0c;图件的本体只有1个&#xff0c;分幅图中只有布局试图有点线面等实体存在&#xff0c;模型…

阿里二面:用过GC日志可视化工具进行JVM调优吗?

上周有个小伙伴面了阿里&#xff0c;在二面中被问到GC日志分析&#xff0c;感觉回答的不是很好&#xff0c;过来找我复盘&#xff0c;大致听了他的回答&#xff0c;虽然回答出了部分&#xff0c;但是没抓到重点。 GC日志分析算是JVM调优中比较难的部分&#xff0c;今天这篇文章…

0123 双指针 Day12

剑指 Offer 25. 合并两个排序的链表 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1&#xff1a; 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1->1->2->3->4->4 /*** Definition for si…

安科瑞嵌入式多功能计量表AEM96 精度0.5S级 2-31次分次谐波

安科瑞 王晶淼/刘芳 一、产品概述 AEM系列三相嵌入式电能计量表是一款主要针对电力系统、工矿企业、公用设施的电能统计、管理需求而设计的智能电能表&#xff0c;集成三相电力参数测量及电能计量与考核管理&#xff0c;提供上24时&#xff0c;上31日以及上12月的电能数据统计…

DNS 区域传送漏洞(dns-zone-tranfer)学习

DNS 区域传送漏洞&#xff08;dns-zone-tranfer&#xff09;学习 ———— 相关知识理解 DNS&#xff08;域名系统&#xff09;就像一个互联网电话簿。它负责将人类可读的主机名解析为机器可读的 IP 地址。 DNS服务器分为主服务器&#xff0c;备份服务器&#xff0c;缓存服务…

【Docker】多个容器和宿主机之间如何进行数据同步和数据共享?容器数据卷从介绍到常用操作图文教程

专栏往期文章 《Docker是什么&#xff1f;Docker从介绍到Linux安装图文详细教程》《30条Docker常用命令图文举例总结》《Docker如何构建自己的镜像&#xff1f;从镜像构建到推送远程镜像仓库图文教程》 前言 你是否担心 Docker 容器被删除后&#xff0c;容器内的重要数据就丢…

VFIDILDKVENAIHNAAQVGIGFAKPFEKLINPK,果蝇抗菌肽

果蝇抗菌肽是一种含有Lys的抗菌多肽&#xff0c;序列中包含34个氨基酸&#xff0c;是一种含有α-折叠的抗菌多肽。 编号: 223981中文名称: 果蝇抗菌肽&#xff0c;Andropin英文名: Antimicrobial Peptide Andropin单字母: H2N-VFIDILDKVENAIHNAAQVGIGFAKPFEKLINPK-OH三字母: H2…

自然语言处理(NLP)数据集汇总 3(附下载链接)

&#x1f384;&#x1f384;【自然语言处理NLP】简介 &#x1f384;&#x1f384; 自然语言处理(Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门…

Allure:根据step动态设置description

背景 使用pytestAllure进行自动化的时候,为了报告展示更明确会使用 with allure.step(xxx)和 allure.step(xxx)测试结束后就可以看到 测试步骤 Allure还支持配置Description 之前直接在case中编写,例如 """ [用例描述]: 专家问诊 [前置步骤]:1. 打开h5页面…

ScheduledExecutorService的使用及守护线程

只运行一次 private static ScheduledExecutorService scheduler; public static void main(String[] args) throws Exception { scheduler Executors.newScheduledThreadPool(5); // 循环任务&#xff0c;按照上一次任务的发起时间计算下一次任务的开始时间 scheduler.schedu…

解决mysql存储emoji表情唯一索引报错问题

问题发现&#xff1a; 1、正常上班的一天&#xff0c;突然间有运营同事反馈&#xff0c;我们在添加数据的时候&#xff0c;发现添加了&#x1f438;之后&#xff0c;对应的&#x1f4a9;没有了&#xff0c;添加了&#x1f4a9;然后&#x1f438;就没有了&#xff0c;需要研发帮…

【Linux】四、Linux 进程概念(四)|进程地址空间

目录 十、进程地址空间 10.1 回顾C/C 地址空间 10.2 测试 10.3 感性理解虚拟地址空间 10.4 如何画大饼&#xff1f; 10.5 如何理解区域划分和区域调整 10.6 虚拟地址空间、页表和物理地址 10.7 为什么存在地址空间 10.7.1 保证物理内存的安全性 10.7.2 保证进程的独立…

铁蛋白-海藻酸钠纳米包埋ACE抑制肽|海藻酸钠修饰碳纳米管(SAL-MWNTs)

铁蛋白-海藻酸钠纳米包埋ACE抑制肽|海藻酸钠修饰碳纳米管(SAL-MWNTs) 铁蛋白-海藻酸钠纳米包埋ACE抑制肽产品描述&#xff1a;利用铁蛋白在较酸条件下可逆组装特性和海藻酸钠(sodium alginate,SA)的控释作用,以马脾脱铁铁蛋白(horse spleen apoferritin,HSF)和SA作为纳米载体,…

Rust 基础(八)—— 高级特性

十九、高级特性 到目前为止&#xff0c;您已经学习了Rust编程语言最常用的部分。在我们开始第20章的下一个项目之前&#xff0c;我们先来看一下你可能偶尔会碰到&#xff0c;但不是每天都在使用的语言的一些方面。当你遇到任何未知的情况时&#xff0c;你可以使用这一章作为参…

[毕业设计]2022-2023年最新最全计算机专业毕设选题推荐汇总

目录 ①javaweb信息管理系统或web应用选题(应用开发类) ②微信小程序开发方向 ③游戏动画、数字媒体方向 ④深度学习、机器学习方向 ⑤算法研究方向 ⑥物联网、嵌入式方向 ⑦信息安全、网络安全 ⑧大数据分析、大数据预测 ⑨Matlab 选题迷茫 选题的重要性 选题指导 对毕…

Springboot利用Security做OAuth2资源服务器

Springboot利用Security做OAuth2授权验证_LO嘉嘉VE的博客-CSDN博客_springbootsecurity oauth2 密码认证 验证服务器在上一篇文章中. 验证服务器是做权限验证&#xff0c;有没有登录&#xff0c;有没有权限访问某些内容等。资源服务器指提供业务功能的服务器&#xff0c;他们…

使用idea创建springboot项目

一、第一种创建方法 点击File——>New——>Project 接下来选择空项目&#xff0c;如下图所示&#xff1a; 接下来点击Next——>项目名称——>finish 点击finish后会弹出如下图&#xff0c;让你新建一个Moudles 如下图&#xff0c; 在项目结构里面点击Modules——…

Kubeadm 部署 k8s 集群

目录 1.初始化设置 2.所有节点安装docker 3.k8s节点安装kubeadm&#xff0c;kubelet和kubectl 4.部署K8S集群 5.部署Dashboard 6.部署harbor私有仓库 名称设置组件master192.168.116.70&#xff08;2C/4G&#xff0c;cpu核心数要求大于2&#xff09;docker、kubeadm、ku…

南开大学程明明-学术规范及论文写作指导

第一讲 学术规范与论文写作-写作规范 主要内容 why writing is important 导致剽窃的原因&#xff08;引用不当也会导致&#xff09;&#xff1a; 引用不是介绍别人的工作&#xff0c;而是更加清晰介绍自己的工作 第二讲 学术规范与论文写作-WrittingTips 各种工具的使用 Ove…