当前位置: 首页 > news >正文

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 架构 &#xf…...

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…...