Java中的锁概述
java中的锁
java添加锁的两种方式:
synchronized:关键字 修饰代码块,方法 自动获取锁、自动释放锁
Reentrantlock:类 只能修饰代码块 手动加锁、释放锁
java中锁的名词
一些锁的名词指的是锁的特性,设计,状态,并不是都是锁。
乐观锁(实际是没有锁):
认为并发操作,不加锁的方式实现是没有问题的,每次操作前判断(CAS,自旋思想)是否成立,是一种不加锁实现
乐观锁和悲观锁不是指具体的什么类型的锁,可以将其看做一种解决并发同步问题的角度。
悲观锁:
认为并发操作肯定会有问题的,所以必须加锁,是加锁的实现。
总结:乐观锁适合读操作多的场景,悲观锁适合写操作多的场景。
可重入锁:
又名递归锁,是指在同一个线程在外层方法获取锁得时候,可以获取到内部其他同步方法的同步锁。
读、写锁:
ReentrantReadWriteLock
支持读,写加锁;如果都是读操作,加锁,这个读锁可以被多个读操作的线程共享;如果一旦有写操作,加写锁,读写互斥
分段锁:
并非一种实际的锁,是一种思想,将锁的粒度拆分,提高效率;如ConcurrentHashMap
自旋锁:
并非一种实际的锁,是以自旋的方式重新获取锁,自己重试,当线程抢锁失败,就重试几次,成功了就继续,抢不到则线程阻塞
共享锁:
锁可以被多个线程所持有共享,如读写锁中的共享锁;
独占锁:
是互斥锁,同一时间该锁一次只能有一个线程持有,如synchronized;
公平锁:
按照请求锁的顺序获取锁,就是可以根据线程的先来后到公平的获取锁,例如ReentrantLock可以实现公平锁
非公平锁:
没有先来后到,谁抢到谁获得执行权,ReentrantLock也可以实现非公平锁,Synchronized是非公平锁。
Synchronized锁实现
Synchronized锁是依赖底层编译后的指令来控制的,需要我们提供一个同步对象,来记录锁状态。
java中Synchronized通过在对象头设置标记,记录锁状态,多个线程需要是同一个锁对象(在定义线程类时,创建一个static的对象作为锁对象即可),才可以实现加锁控制的目的,达到获取锁和释放锁的目的。
在Synchronized锁的底层实现中,提供锁的状态,用来区别对待,这个锁的状态存储在同步锁对象的对象头中,有一个区域叫Mark Word中存储。这几个状态是根据条件不断攀升的,目的还是优化,如下:
无锁状态
偏向锁状态:一直是一个线程访问, 记录线程的id,快速访问
轻量级锁状态:当锁状态为偏 向锁时,又继续有其他线程来访问,此时升级为轻量级锁;没有获取到锁的线程,不会阻塞,而是继续不断尝试获取锁
重量级锁状态:当锁状态为轻量级锁时,线程自旋达到一定的次数时,进入阻塞状态,锁状态升级为重量级,等待操作系统调度
再次普及一下对象头的概念:
对象的结构
实例对象在内存中的布局分为三个区域:对象头、实例数据、对齐填充。
对象头:对象头中有一块叫Mark Word的区域,用于存储自身的运行时数据,如哈希码(HashCode)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID。
实例数据:实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。
对齐填充:第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。
在介绍其他锁之前,先要认识AQS:
AQS
Abstract Queued Synchronizer 抽象同步队列
位于java.util.concurrent.locks包下,是JUC其他锁实现的基础;
AQS 是一个用来构建锁和同步器的框架,使用 AQS 能简单且高效地构造出同步器 , 是 JUC 中 核 心 的 组 件 , 比如我 们提到的 ReentrantLock,CountDownLatch 等等都是基于 AQS 来实现。
只要搞懂了 AQS,那么 JUC类中的绝大部分api都可以搞定
AQS思路
在类中维护一个state变量,然后维护一个队列,以及获取锁,释放锁的方法;
当线程创建后,先判断state值,为0,没有线程使用,把state=1,执行完成后,将state=0,期间如果有其他的线程访问,state若等于1,将其他线程放入类中的队列中。(公平的实现)
AQS 的锁模式分为独占和共享
独占锁:每次只能有一个线程持有锁,比如 ReentrantLock 就是以独占方式实现的互斥锁。
共 享 锁 : 允 许 多 个 线 程 同 时 获 取 锁 , 并 发 访 问 共 享 资 源 , 比 如ReentrantReadWriteLock
ReentrantLock锁
无参构造默认是非公平实现,参数为true- 公平实现,false-非公平实现;
ReentrantLock 类内部总共存在 Sync、NonfairSync、FairSync 三个类, NonfairSync 与FairSync 类 继 承 自Sync 类 , Sync 类 继 承自 AbstractQueuedSynchronizer 抽象类。
abstractstaticclassSyncextendsAbstractQueuedSynchronizer
非公平实现(源码)
staticfinalclassNonfairSyncextendsSync {
//加锁
finalvoidlock() {
//若通过 CAS 设置变量 state 成功,就是获取锁成功,则将当前线程设置为独占线程。
//若通过 CAS 设置变量 state 失败,就是获取锁失败,则进入 acquire 方法进行后续处理。if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);
}//尝试获取锁,无论是否获得都立即返回protectedfinalbooleantryAcquire(intacquires) {returnnonfairTryAcquire(acquires);}
}
公平实现(源码)
staticfinalclassFairSyncextendsSync { finalvoidlock() { // 以独占模式获取对象,忽略中断 acquire(1);//底层实现交由 AbstractQueuedSynchronizer } }
JUC包中的常用类:
这些都是线程安全的实现类,底层都是基于AQS实现
ConcurrentHashMap
Hashtable:线程安全的,但直接锁住的是整个方法,效率低;
ConcurrentHashMap:是线程安全的实现类,效率是高于Hashtable的;
hashMap和ConcurrentHashMap都不能存储键值为null的元素,比如get方法,返回的是一个null,我们无法确定集合中不存在这个键,还是这个键对应的值是null,就是模糊不清的。
CopyOnWriteArrayList
将读取的操作发挥到机制,读读、读写都不是互斥的,且读的时候不加锁,写的时候加锁。提高读的效率;
实现原理是:在进行add,set等修改操作时,先将数组进行备份,对备份的数组进行修改,完成后,将修改后的数组赋值给原数组,提高了读的效率
CopyOnWriteArraySet
注:去重方式与Set集合是不一样的;
不能存储重复数据,是线程安全的
CountDownLatch辅助类
可以实现让一个线程暂停,等待其他线程各自执行完毕后再自动执行。底层实现也是通过AQS实现的,创建一个CountDownLatch对象后时构造方法中传入一个值,就是state的值,每当一个线程执行完毕,state就-1,直到所有线程都执行完,state等于0时,暂停的线程就可以回复工作了。
相关文章:
Java中的锁概述
java中的锁java添加锁的两种方式:synchronized:关键字 修饰代码块,方法 自动获取锁、自动释放锁Reentrantlock:类 只能修饰代码块 手动加锁、释放锁java中锁的名词一些锁的名词指的是锁的特性,设计,状态&am…...

微电影行业痛点解决方案
在当下新媒体时代,微电影作为“微文化”的载体,具有“微”的特点,经过短短数年的快速发展,并获得了受众广泛的关注和喜爱,对人们的休闲娱乐方式也产生较大的影响。但在迅猛发展的同时也存在一些行业痛点,诸…...

使用Spring框架的好处是什么
使用Spring框架的好处是什么? 1、轻量:Spring 是轻量的,基本的版本大约2MB。 2、控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。 3、面向切面的编程(AOP…...

【表格单元格可编辑】vue-elementul简单实现table表格点击单元格可编辑,点击单元格变成弹框修改数据
前言 这是继我另一个帖子就是单元格点击变成输入框后添加的功能 因为考虑到有些时候修改单元格的信息可能点击后要修改很多,那一个输入框不好用 所以这时候就需要一个弹框可以把所有表单都显示出来修改 所以这里就专门又写了一个demo,用于处理这种情况 …...

vue3.0 响应式数据
目录1.什么是响应式2. 选项式 API 的响应式数据3.组合式 API 的响应式数据3.1 reactive() 函数3.2 toref() 函数3.3 toRefs() 函数3.4ref() 函数总结1.什么是响应式 这个术语在今天的各种编程讨论中经常出现,但人们说它的时候究竟是想表达什么意思呢?本质…...

uni-app ①
文章目录一、uni-app简介学习 uniapp 本质uniapp 优势uni-app 和 vue 的关系uni-app 和小程序有什么关系uniapp 与 web 代码编写区别课程内容学习重点知识点一、uni-app 简介 uni-app 是一个使用 Vue.js 进行 开发所有前端应用的框架。开发者编写一套代码,即可发布…...
20个 Git 命令玩转版本控制
想要在团队中处理代码时有效协作并跟踪更改,版本控制发挥着至关重要的作用。Git 是一个版本控制系统,可以帮助开发人员跟踪修订、识别文件版本,并在必要的时候恢复旧版本。Git 对于有一定编程经验的用户来说虽然不算太难,但是想要…...

SAP NetWeaver版本和SAP Kernel版本的确定
SAP NetWeaver(SAP NW)描述了用于“业务启用”的所有软件和服务。SAP业务套件(如ERP中央组件(ECC)或供应商关系管理(SRM))包含该特定业务解决方案的软件组件。 以下是SAP NetWeaver…...

面试23K字节测试开发岗被血虐,到底具有怎样的技术才算高级水平?
前几天我朋友跟我吐苦水,这波面试又把他打击到了,做了6年软件测试。。。 下面这条招聘是在腾讯招聘官网截图下来的,首先我们对高级水平下一个定义吧,那它应该是对标这个职级该有的能力 什么样的工程师才能算高级?至少…...

智云通CRM:买对了吗——大客户采购的方案实施
一旦采购合同签署后,供应商就要履行合同,按时交付产品进场使用,或实施服务方案。不过,无论对供应商还是客户来说,双方的合作并没有就此结束。 在这个阶段,客户会评估此次合作的供应商做事是否靠谱&#x…...

前后端开发过程中的跨域问题总结
1.何为跨域问题 出于浏览器的同源策略限制。同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能不能使用。可以说web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。…...

爬虫:栖落的电影网站,利用requests和re模块
这是栖落的电影网站地址:https://xxx.xxx 进入网页,显示: 爬取目标:电影的名称、观影人数和评分。 易知本网站的url url "https://xxx.xxx" 本网站会识别出headers中的python请求而拒绝访问,所以需要更改…...

使用burpsuite抓包 + sql工具注入 dvwa靶场
使用burpsuite抓包 sql工具注入 dvwa靶场 记录一下自己重新开始学习web安全之路②。 一、准备工作 1.工具准备 sqlmap burpsuite 2.浏览器准备 火狐浏览器 设置代理。 首先,先设置一下火狐浏览器的代理 http代理地址为127.0.0.0.1 ,端口为8080 …...

树与图中的dfs和bfs—— AcWing 846. 树的重心 AcWing 847. 图中点的层次
一、AcWing 846. 树的重心1.1题目1.2思路分析题意:什么是树的重心?树的重心是指,删除某个结点后剩下的最大连通子树的结点数目最小,如下图是根据样列生成的树,若删除结点1,则剩下三个子树最大的是中间那颗结…...

从零开始学数据分析之数据分析概述
当今世界对信息技术的依赖程度在不断加深,每天都会有大量的数据产生,我们经常会感到数据越来越多,但是要从中发现有价值的信息却越来越难。 这里所说的信息,可以理解为对数据集处理之后的结果,是从数据集中提炼出的可…...

十五载厚积薄发,电信级分布式数据库是这样炼成
所在论坛:数据库技术创新&云原生论坛 分享时段:2.18 10:00-10:30 分享主题:大规模并行处理:AntDB分布式演进之路 分享嘉宾:沈夺,亚信科技AntDB数据库内核开发工程师 由中国开源软件推进联盟Postgre…...
Centos调整分区存储大小
将/home下900G转移到/目录下 1、查看分区大小:df -hl 2、备份home文件:tar cvf /run/home.tar /home 3、终止home文件进程(切换到非home路径下执行这个命令):fuser -km /home 3.1、如果没有fuser,在线安装…...
华为OD机试真题JAVA实现【单词接龙】真题+解题思路+代码(20222023)
华为OD机试真题JAVA实现【单词接龙】真题+解题思路+代码(2022&2023) 🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输…...
Mapbox Style 规范
Mapbox致力于打造全球最漂亮的个性化地图。 中文官网经常打不开所以做下记录,方便查阅。 Web 端 API Mapbox GL JS 的地图样式规范 Style 的各个配置项: (必填项会加上 * ,方便根据目录进行查看) 配置项:1.…...

Java开发学习(五十)----MyBatisPlus快速开发之代码生成器解析
1、代码生成器原理分析 造句: 我们可以往空白内容进行填词造句,比如: 在比如: 观察我们之前写的代码,会发现其中也会有很多重复内容,比如: 那我们就想,如果我想做一个Book模块的开发,是不是只需要将红色部分的内容全部…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...