锁策略和synchronized

news2024/11/19 2:39:16

1.常见的锁策略

(1)乐观锁 和 悲观锁

乐观锁:预测锁竞争的情况不激烈(工作量较少)

悲观锁:预测锁竞争的情况很激烈(工作量较多)

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

轻量级锁:加锁和解锁的开销较小,效率更高。(乐观锁通常是一个轻量级锁)

重量级锁:加锁和解锁的开销较大,效率较低。(悲观锁通常是一个重量级锁)

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

自旋锁:是一种典型的轻量级锁,会不断去尝试获取锁。

挂起等待锁:是一种典型的重量级锁,会进入阻塞队列,暂时不参与cpu调度。

(4)互斥锁 和 读写锁

互斥锁:synchronized锁就是一个互斥锁,如果一个线程加锁了,另一个线程要获取锁,会进入阻塞等待。

读写锁:如果多个线程都只进行读操作,那么此时是没有线程问题的,无需加锁。而如果在锁中的代码有读也有写,或者全是写(简单来说就是代码中带有写操作)才会进行加锁。

(5)公平锁 和 非公平锁

公平锁:假如有两个线程一个阻塞等待了1分钟,一个等待10秒钟,此时锁被释放会先给等待时间长的加锁。

非公平锁:仍然是上面的情况,但是此时它们的获取概率相等。

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

可重入锁:一个线程重复加多次锁,不会死锁。

不可重入锁:一个线程重复加两次锁,会出现死锁。

2.synchronized实现了哪些锁策略

(1)synchronized既是一个乐观锁又是一个悲观锁

默认是乐观锁,如果竞争激烈会转变为悲观锁。

(2)synchronized既是一个轻量级锁又是一个重量级锁

默认是轻量级锁(乐观锁),如果竞争激烈会转变为重量级锁(悲观锁)。

(3)synchronized的轻量级锁是基于自旋锁的方式实现的;synchronized的重量级锁是基于挂起等待锁的方式实现的。

(4)synchronized是互斥锁,不是读写锁

(5)synchronized是非公平锁

(6)synchronized是可重入锁

3.synchronized原理

synchronized的工作原理是当两个线程针对同一个对象加锁时,会产生阻塞等待。

除此之外,synchronized的内部还有一些优化机制,目的是为了让这个锁更加高效好用。

3.1 锁升级/锁膨胀

synchronized在加锁后会进入这样的几种状态。

(1)无锁

此时synchronized没有被加锁

(2)偏向锁

此时有线程对其加锁,但是此时的加锁并非真正的加锁操作,只是在锁对象上打了一个标记,并没有进行实际的加锁操作,此时的偏向锁比起真正的加锁的开销要少了很多,但是这种状态只存在与没有锁竞争的情况下,如果有其他线程对其尝试加锁,那么就会进行真正的加锁操作,反之,如果执行到了末尾也没有其他线程来加锁,此时就不会加锁,直接把标记消除掉就好了。

(3)轻量级锁

当在偏向锁的阶段有其他线程对其进行加锁,也就是发生锁竞争的时候,那么偏向锁就会升级成为轻量级锁,此时会通过自旋锁的方式进行加锁的,但是不断的去获取锁也会占用cpu资源。此时,如果加锁的线程很快就将锁释放掉,那么自然相安无事,此时的自旋也是划算的;但是,如果迟迟拿不到锁,也就是自旋到一定程度时,就会升级成为重量级锁(挂起等待锁)。

(4)挂起等待锁

如果线程进行了重量级锁的加锁,并且发生了锁竞争,此时竞争的线程就会放入到阻塞队列中,暂时不参与cpu的调度,直到锁被释放,这个线程才有机会被调度到,并且有机会获取锁。

注意:锁的升级是不可以倒退的。

3.2 锁消除

锁消除是编译器的一种智能判定,判断当前代码是否真的需要加锁。

如果加锁代码在某个场景中没有线程安全问题,不需要加锁,那么编译器就会把锁给干掉。

比如StringBuffer,它的关键方法都带有synchronized,但是如果我在单线程的环境下去使用它,那么它的加锁操作就会变得毫无意义,此时编译器就会将锁给干掉了。

3.3 锁粗化

通常情况下,我们希望锁的粒度越细越好,也就是加锁的代码越少越好,因为锁的粒度越细,可以被并发的代码就越多,反之就越少。

但是在有些情况下,锁的粒度反而粗一点会更好,如下:

图中被红色圈住的部分是要加锁的代码,没被圈住的部分是可以不加锁的代码,此时可以看到,每次的解锁与加锁之间的间隔非常的小,因为加锁和解锁的操作也是有一定开销的,在一段代码中频繁大量的进行加锁解锁操作,那么并发带来的效益可能还不如频繁加锁的带来消耗多。就好比:

我完成了三个工作,要汇报给自己的领导

打电话--汇报工作1--挂电话 间隔一分钟

打电话--汇报工作2--挂电话 间隔一分钟

打电话--汇报工作3--挂电话

此时领导一定被你烦的不行,为什么不可以一次性汇报完呢?

在这里也是同样的道理,打电话相当于加锁,挂电话相当于解锁,如果将那些小的间隔也一并加入锁中,如下:

此时,将多个加锁操作合并为一个整体,就可以将上述的情况解决了。

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

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

相关文章

IDEA Alibaba代码格式化(EclipseCodeFormatter)

1.阿里模板下载地址https://github.com/alibaba/p3c/tree/master/p3c-formatter2.下载阿里配置文件(eclipse-codestyle.xml),因为此文件是针对ecplice的,在IDEA中使用配置文件,需要安装Eclipse Code Formatter插件3.配…

文档控件 Aspose.PDF for Java 授权须知

Aspose.PDF是一款高级PDF处理API,可以在跨平台应用程序中轻松生成,修改,转换,呈现,保护和打印文档。无需使用Adobe Acrobat。此外,API提供压缩选项,表创建和处理,图形和图像功能&…

马蹄集 卡罗尔数

卡罗尔数 难度&#xff1a;白银 0时间限制&#xff1a;1秒 巴占用内存&#xff1a;64M 卡罗尔数是其值满足4n-2(n1)-1的整数(n为正整数)。输入正整 数N判断它是不是卡罗尔数&#xff0c;输出YES或者NO。 #include <bits/stdc.h>> using namespace std; int main(…

SpringMVC超详解

SpringMVC超详解1、SpringMVC简介1.1、什么是MVCMVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据JavaBean分为两类&#xff1a;一类称为实体类Bean&…

算法拾遗二十四之暴力递归到动态规划二

算法拾遗二十四之暴力递归到动态规划二背包问题一优化题目二优化题目三&#xff08;贴纸拼词&#xff09;优化题目四&#xff1a;最长公共子序列优化背包问题一 weights[i]和values[i]的值都是大于等于0的&#xff0c;不存在负数的情况。 可以从尝试入手&#xff0c;改动态规划…

基于智能矿山电力监控系统的设计与应用方法

摘要&#xff1a;随着煤矿建设的智能化程度越来越高&#xff0c;构建智能电力监控系统实现对矿山生产的有效监控至关重要。首先分析了矿山电力监控系统存在的主要问题&#xff0c;其次重点介绍了基于智能矿山电力监控系统的设计过程&#xff0c;后提出了加强智能电力监控系统的…

Inspur KOS 龙蜥衍生版面向智慧新媒体转型的探索与实践 | 龙蜥案例

编者按&#xff1a;日前&#xff0c;龙蜥社区理事单位浪潮信息正式对外发布基于龙蜥操作系统&#xff08;Anolis OS&#xff09;的服务器操作系统 Inspur KOS&#xff0c;并基于 Inspur KOS 推出可视化迁移方案 C2K&#xff0c;该方案能够将用户应用安全可靠地切换到 Inspur KO…

【系列02】Java流程控制 scanner 选择结构 循环结构语句使用 [有目录]

Scanner输入 Next和NextLine区别 NextLine 用的会多点 因为Next遇到空格就断开了 next语法使用 package com.SunAo.scanner; import java.util.Scanner; public class Demo01 {public static void main(String[] args) {//创建扫描器用来接收 键盘输入Scanner scanner new …

李宏毅ML-批次与动量

批次与动量 文章目录批次与动量1. Small batch or Large batch?2. Gradient descent Momentum3. 总结1. Small batch or Large batch? 在使用 gradient descent 进行 optimization 时&#xff0c;在每一次 epoch 前&#xff0c;要 shuffle 所有的资料&#xff0c;然后再分成…

无桌面Centos7系统安装Cypress@9.0.0并运行

一、安装Cypress 安装前准备 1、安装npm 下载安装包 cd /usr/local mkdir node cd node wget https://npm.taobao.org/mirrors/node/v15.8.0/node-v15.8.0-linux-x64.tar.gz ls -l解压这个包 tar -zxvf node-v15.8.0-linux-x64.tar.gz 你会发现已经有一个node的目录解压…

11、Javaweb_JSPMVCELJSTL三层架构用户列表案例

JSP: 1. 指令 * 作用&#xff1a;用于配置JSP页面&#xff0c;导入资源文件 * 格式&#xff1a; <% 指令名称 属性名1属性值1 属性名2属性值2 ... %> * 分类&#xff1a; 1. page &#xff1a; 配置JSP页面的 * content…

①【Spring】一文了解IOC容器

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 一文掌握IOC一、IOC二、IOC容器的实现BeanFact…

一文掌握fastapi微服务开发

目录 一、概述 1.1 微服务 1.1.1 微服务的优势 1.1.2 微服务的缺点 1.2 为何使用Python开发微服务 1.3 FastAPI概述 二、开发 2.1 安装FastAPI 2.1.1 安装虚拟环境 2.1.2 创建虚拟环境 2.1.3 激活虚拟环境 2.1.4 安装FastAPI 2.2 FastAPI简单使用 2.2.1 查询 2.…

java注解以及如何利用反射获取注解的属性值

一、什么是注解 1.Annotation是从JDK5.0开始引入的新技术 2.Annotation的作用 : &#xff08;1&#xff09;不是程序本身&#xff0c;可以对程序作出解释(这一点和注释(comment)没什么区别)&#xff08;2&#xff09;可以被其他程序(比如:编译器等)读取 3.Annotation的格式…

【每日一题】【LeetCode】【第十一天】杨辉三角

解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 杨辉三角感觉还是挺经典的代码题目&#xff1f;之前大一学C语言好像写过一次。 不过&#xff0c;自己当时就不会写&#xff0c;这次自己先试试能不能想出解决方案。 输入数字是几&#xff0c;那就要输出几…

亚马逊云科技帮助Gemsouls在云上快速实现技术验证与部署

元宇宙热度居高不下&#xff0c;它所创造的虚拟世界进一步拉近了人与人之间的距离&#xff0c;用数字化的形式消除地理与空间上的隔阂。而高度拟真化的虚拟人与AI虚拟社交&#xff0c;是元宇宙落地的重要领域&#xff0c;打造以人工智能驱动的虚拟人社交平台已成为行业大势。 …

DNS 的一些基础知识,以及 DNS 转换域名的过程

DNS(Domain Name System)&#xff0c;主要作用是将域名转成 IP&#xff0c;本文主要讲解了 DNS 的一些基础知识&#xff0c;以及 DNS 转换域名的过程。DNS 是什么dig命令绝大多数网络通信都是基于 TCP/IP 协议&#xff0c;而 TCP/IP 协议的基础是 IP&#xff0c;所以网络中的计…

获取未来时间 一年或N年

需求 展示从本月初开始 一年的时间 或N年的时间 以便用户选择思路 一年12个月 是已知的 从本月到12月可以生成本年的每天数据从1月至上月可以生成所需得到最后一年的数据今年加最后一年的月份可拼接一年时间 所以中间年份是所需年分-1的数组数据中间年份都是1-12月 可以通过年份…

软件的生命周期和测试的生命周期的区分

软件的生命周期测试的生命周期软件测试贯穿于软件的整个生命周期在需求分析阶段测试人员的活测试人员需要站在用户角度分析&#xff1a;软件需求是否合理&#xff1b;站在技术角度分析&#xff1a;技术上是否可行&#xff0c;还有没有优化的空间&#xff1b;站在测试角度分析&a…

VALL-E:微软全新语音合成模型可以在3秒内复制任何人的声音

近日&#xff0c;微软研究人员宣布了一种新的语音合成AI模型 VALL-E&#xff0c;给出3秒样音就可以精确地模拟一个人的声音。一旦它学会了一个特定的声音&#xff0c;VALL-E可以复制说话者的情绪和语气&#xff0c;即使说话者本人从未说过的单词也可以模仿。 论文地址&#xf…