Java 多线程 --- 锁的概念和类型划分
Java 多线程 --- 锁的概念和类型划分
- 锁的概念
- 乐观锁与悲观锁
- 公平锁与非公平锁
- 什么是可重入锁
- 独占锁与共享锁
- 轻量级锁和重量级锁
- 自旋锁 (Spinlock)
锁的概念
- 锁可以将多个线程对共享数据的并发访问转换为串行访问, 这样一个共享数据一次只能被一个线程访问, 该线程访问结束后其他线程才能对其进行访问.
- 锁具有排他性 (Exclusive), 即一个锁一次只能被一个线程持有. 所以这种锁被称为排他锁或者互斥锁 (Mutex).
乐观锁与悲观锁
- 乐观锁和悲观锁严格的说不是一种锁,而是一种策略
悲观锁
- 加锁是一种悲观的策略,它总是认为每次访问共享资源的时候,总会发生冲突,所以宁愿牺牲性能(时间)来保证数据安全
- 悲观锁的使用场景并不少见,数据库很多地方就用到了这种锁机制,比如行锁,表锁,读锁,写锁等,都是在做操作之前先上锁,悲观锁的实现往往依靠数据库本身的锁功能实现。Java程序中的Synchronized和ReentrantLock等实现的锁也均为悲观锁。
乐观锁
- 乐观锁就是先不加锁. 无锁是一种乐观的策略,它假设线程访问共享资源不会发生冲突,所以不需要加锁,因此线程将不断执行,不需要停止。一旦碰到冲突,就重试当前操作直到没有冲突为止
- 无锁的策略之一就是使用CAS机制
CAS机制
- CAS的全称是Compare-and-Swap,也就是比较并交换,它包含了三个参数:V,A,B,
- V表示要读写的内存位置,A表示旧的预期值,B表示新值
- 具体的机制是,当执行CAS指令的时候,只有当V的值等于预期值A时,才会把V的值改为B,如果V和A不同,有可能是其他的线程修改了,这个时候,执行CAS的线程就会不断的循环重试,直到能成功更新为止
- CAS算是比较高效的并发控制手段,不会阻塞其他线程。但是,这样的更新方式是存在问题的,看流程就知道了,如果C的结果一直跟预期的结果不一样的话,线程A就会一直不断的循环重试,重试次数太多的话对CPU也是一笔不小的开销。
- CAS的ABA问题
- CAS还有个问题就是ABA问题,比如第一次拿到内存里的值时是A,然后被其他线程修改为B, 然后又修改为A, 而此时去比较内存里的值会发现没有变,但是实际上还是有改动
- 举个通俗点的例子,你倒了一杯水放桌子上,干了点别的事,然后同事把你水喝了又给你重新倒了一杯水,你回来看水还在,拿起来就喝,如果你不管水中间被人喝过,只关心水还在,还好 ; 但是假若你是一个比较讲卫生的人,那你肯定就不高兴了
- ABA问题的解决思路: 使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A→B→A就会变成1A→2B→3A了
公平锁与非公平锁
公平锁
- 公平锁的概念是如果当前一个线程已经获取到锁了,其他线程如果再想获取到锁的话需要排队.
非公平锁
- 非公平锁的概念是如果当前一个线程已经获取到锁了,那么新来的线程如果再想获取到锁先CAS抢一下,如果抢到了就执行代码,抢不到在去排队
Java中的公平锁和非公平锁
- JDK中的ReentrantLock既支持非公平锁又支持公平锁,默认非公平锁
- Synchronized则是非公平锁
优缺点
- 公平锁的优点是等待锁的线程不会饿死。缺点是整体吞吐效率相对非公平锁要低,等待队列中除第一个线程以外的所有线程都会阻塞,CPU 唤醒阻塞线程的开销比非公平锁大
- 非公平锁的优点是可以减少唤起线程的开销,整体的吞吐效率高,因为线程有几率不阻塞直接获得锁,CPU 不必唤醒所有线程。缺点是处于等待队列中的线程可能会饿死,或者等很久才会获得锁
什么是可重入锁
- 所谓重入锁,即一个线程如果获取到了锁,那么这个线程再下一次进入同步代码中的时候可以直接进入,不用重新获取锁,
- 我们最熟悉的sychronized和ReentrantLock都是可重入锁。其实从ReentrantLock的名称上就可以看出来,Reentrant这个单词翻译成中文就是可重入的意思.
- ReentrantLock可重入锁的实现,记录一下当前获取锁的线程记录为ownerThread,如果当前线程在获取锁的时候,发现自己就ownerThread,那么当前线程可以不用去抢锁直接执行
独占锁与共享锁
- 独占锁的概念是如果有一个线程已经获取到了锁,其他线程不可以继续获取锁,锁只能有此线程独占。
- 共享锁的概念是一个锁可以有多个线程共享,即一个线程获取到了锁,其他线程还可以继续获取锁
- 基于AQS实现的ReentrantLock就是独占锁,而AQS也提供了实现共享锁的模版方法tryAcquireShared.
轻量级锁和重量级锁
- 重量级锁的概念是如果锁已经被持有了,当前线程获取不到锁,当前线程挂起,等待锁的释放以及被唤醒。
- 轻量级锁的概念是如果锁已经被持有了,当前线程获取不到锁,那么将使用CAS机制或者自旋的方式获取锁 (在Java中Synchronized的轻量级锁是用自旋锁实现的)
- 这样设计的原因是大部分情况下我们占用锁的线程很快就执行完了,在很短的时间内就释放了锁,
- 如果使用重量级锁,那么下一个线程想获取锁继续执行的话需要经历挂起以及唤醒,这个过程需要CPU上下文切换,这个时间开销甚至大于用户代码执行的时间,所以轻量级锁让线程等一会,锁一旦释放,当前线程可以立马获取到,省去了不必要的上下文切换的开销
- JVM对Synchronized锁的优化就是从无锁到重量级锁的升级过程
- 无锁->偏向锁->轻量级锁->重量级锁
自旋锁 (Spinlock)
- 自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
- 获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。
相关文章:

Java 多线程 --- 锁的概念和类型划分
Java 多线程 --- 锁的概念和类型划分锁的概念乐观锁与悲观锁公平锁与非公平锁什么是可重入锁独占锁与共享锁轻量级锁和重量级锁自旋锁 (Spinlock)锁的概念 锁可以将多个线程对共享数据的并发访问转换为串行访问, 这样一个共享数据一次只能被一个线程访问, 该线程访问结束后其他…...

python程序员狂飙上头——京海市大嫂单推人做个日历不过分吧?
嗨害大家好鸭!我是小熊猫~ 这个反黑剧其实火了很久了, 但是我现在才有空开始看 该说不说,真的很上头!!! 大嫂简直就像是干枯沙漠里的玫瑰 让人眼前一亮哇~~ 我小熊猫此时此刻就成为大嫂的单推人&…...

浅谈子网掩码、IP地址、网络地址之间关系
文章目录一、什么是子网掩码二、给定IP地址,如何求网络地址网络标识(net-id)和主机标识(host-id)计算步骤三、CIDR地址表示方法(Classless Inter Domain Routing)四、IP地址与MAC地址一、什么是子网掩码 在TCP/IP协议…...
前端优化的解决方案
能缓存的,尽量强缓存。减少HTTP请求数 使用外部引入的css和js文件,并且引入的css和js越少越好使用雪碧图(精灵图)img计算缩放也需要时间,使用base64编码将较小图片嵌入到样式表中,减少请求数因为iframe会阻…...

PYthon组合数据类型的简单使用
Python的数据类型有两种,基本数据类型和组合数据类型,组合数据类型在Python的使用中特别重要。 1.组合数据类型的分类: 2.序列类型 序列类型中元素存在顺序关系,可以存在数值相同但位置不同的元素。序列类型支持成员关系操作符&…...

【Java】P2 基础语法与运算符
Java 基础语法 运算符Java注释方法基本数据类型驼峰命名法Scanner类基本运算除法隐式转换逻辑运算符 以及 短路逻辑运算符三元运算符前言 上一节内容涵盖Java的基础知识,包含安装下载,JDK与JRE等。 链接:https://blog.csdn.net/weixin_43098…...

【并发基础】Java中线程的创建和运行以及相关源码分析
目录 一、线程的创建和运行 1.1 创建和运行线程的三种方法 1.2 三者之间的继承关系 二、Thread类和Runnable接口的区别 2.1 Runnable接口可以实现线程之间资源共享,而Thread类不能 2.2 实现Runnable接口相对于继承Thread类的优点 三、实现 Runnable 接口和实现 Call…...

Spark Shuffle
Shuffle : 集群范围内跨节点、跨进程的数据分发 分布式数据集在集群内的分发,会引入大量的磁盘 I/O 与网络I/O在 DAG 的计算中,Shuffle 环节的执行性能是最差的 , 会消耗所有类型的硬件资源 (CPU、内存、磁盘、网络) Spark 2.0 后,将 Shuff…...

Linux/MacOS 生成双击可执行文件
双击可执行文件包含两种:终端shell脚本 Unix可执行文件 1.终端shell脚本 随意新建一个文件(可使用command键N,前提是有已打开的文件),输入shell格式的测试代码,比如: #! /bin/sh echo “h…...

Ubuntu三种拨号方法
1.宽带拨号(PPPoE) (1)打开连接。关闭以太网连接,打开有线连接设置,取消勾选“自动连接”选项。 (2)配置连接。在终端输入命令sudo pppoeconf,会看到一系列配置信息,包括用户名、密码,配置完成后会有一些提示信息&…...

Vue-router的引入和安装
什么是Vue-Router?Vue路由器是Vue.js的官方路由器,它与Vue.js核心深度集成,使用Vue轻松构建单页应用程序变得轻而易举。功能包括:嵌套路线映射动态路由模块化,基于组件的路由器配置路由参数,查询࿰…...

无线WiFi安全渗透与攻防(四)之kismet的使用
系列文章 无线WiFi安全渗透与攻防(一)之无线安全环境搭建 无线WiFi安全渗透与攻防(二)之打造专属字典 无线WiFi安全渗透与攻防(三)之Windows扫描wifi和破解WiFi密码 kismet 如果要进行无线网络渗透测试,则必须先扫描所有有效的无线接入点。刚好在Kali Linux中&am…...

2023新版PMP考试有哪些变化?
对于2022年很多事情也都在发生,疫情也都没有完全结束,基金会已经开始通知下一场考试了,很多人也会担心新的考纲会不会给自己带来难度,其实这次六月份的考试很多人都内心已经知道了结果,所以这里也详细说一下新考纲的改…...
P8074 [COCI2009-2010#7] SVEMIR 最小生成树
[COCI2009-2010#7] SVEMIR 题目描述 太空帝国要通过建造隧道来联通它的 NNN 个星球。 每个星球用三维坐标 (xi,yi,zi)(x_i,y_i,z_i)(xi,yi,zi) 来表示,而在两个星球 A,BA,BA,B 之间建造隧道的价格为 min{∣xA−xB∣,∣yA−yB∣,∣zA−zB∣}\min\{|x_A-x_…...

10种常见网站安全攻击手段及防御方法
在某种程度上,互联网上的每个网站都容易遭受安全攻击。从人为失误到网络罪犯团伙发起的复杂攻击均在威胁范围之内。 网络攻击者最主要的动机是求财。无论你运营的是电子商务项目还是简单的小型商业网站,潜在攻击的风险就在那里。 知己知彼百战不殆&…...

为什么我选择收费的AdsPower指纹浏览器?
在决定开始用指纹浏览器之前,龙哥让我们团队的运营小哥找了市面上很多产品去测试。最后,还是决定用AdsPower。每个人的使用感受都不一样,龙哥就说说几个用得顺手的几个点。一、指纹环境强大 双内核引擎 市面上指纹浏览器内核都是基于谷歌Chro…...
Java输入输出和数组
一、问答题 1. 如何声明和创建一个一维数组? Int i[]new int[3] 2. 如何访问数组的元素? Int a[]new int a[3] for (int x0;x<a.length;x){ System.out.print(i[x]); } System.out.println(); 3.数组下标的类型是什么?最小的下标是什…...
这些免费API帮你快速开发,工作效率杠杠滴
一、短信发送 短信的应用可以说是非常的广泛了,短信API也是当下非常热门的API~ 短信验证码:可用于登录、注册、找回密码、支付认证等等应用场景。支持三大运营商,3秒可达,99.99%到达率,支持大容量高并发。…...

干货|最全PCB布线教程总结,14条PCB布线原则技巧,保姆级搞定PCB布线
1、坚持手动布线,慎用自动布线2、了解制造商的规格3、合适的走线宽度4、迹线之间留出足够的空间5、元器件放置6、保持模拟和数字走线分开7、接地层8、走线和安装孔留有足够的空间9、交替走线方向10、避免电容耦合11、放置散热孔和焊盘12、接地和电源走线13、利用丝印…...
编程快捷键和markdown语法小计
Data Structure FQA文章目录1.idea快捷键汇总2.markdown一些常用语法1.idea快捷键汇总 altenter 快捷生成变量 altInsert可以新建类,文件,get或set方法,此快捷键又名创造一切 编辑区和文件区的跳转。 alt 1 :编辑区跳转至…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...