Java锁机制

news2025/6/16 10:58:54

Java锁机制

  • 1. 什么是锁
    • JVM运行时内存结构
  • 2. 对象、对象头结构
    • Mark Word中的字段
  • 3. synchronized
    • Monitor原理
    • 四种锁状态的由来
  • 4. 锁的4种状态
    • 4.1 无锁
      • CAS(Compare and Swap)
    • 4.2 偏向锁
      • 实现原理
    • 4.3 轻量级锁
      • 如何判断线程和锁之间的绑定关系
      • 自旋
    • 4.4 重量级锁
  • 5. 总结

1. 什么是锁

在并发环境下,多个线程会对同一个资源进行争抢。可能会导致数据不一致的问题。为了解决这个问题,很多编程语言都引入了锁机制。

通过一种抽象的锁来对资源进行锁定。

JVM运行时内存结构

JVM运行时内存结构主要包含了程序计数器、JVM栈、Native方法栈、堆、方法区。
在这里插入图片描述

最下面一层中蓝色区域是所有线程共享的数据区域。

最下面一层红色区域是各个线程私有的,对于这个区域中的数据,不会出现线程竞争的问题(线程安全)。

Java堆中存放的是所有对象。

方法区中存放的是类信息,常量,静态变量相关信息。

当多个线程竞争其中的一些数据时会发生难以预料的异常情况。因此需要锁机制对其进行限制。

2. 对象、对象头结构

在Java中,每个object,也就是每个对象都拥有一把锁,锁中记录了当前对象被哪个线程所占用。

对象的结构:对象头 + 实例数据 + 对齐填充字节

在这里插入图片描述
在这里插入图片描述
Class Point就是一个指针,指向了当前所在对象类型所在方法区中的类型数据。
在这里插入图片描述

Mark Word中的字段

Mark Word存储了很多和当前对象运行时状态信息有关的数据。比如说hashcode、锁状态标志、指向锁记录的指针、偏向锁ID等等。其中最重要的是锁标志位。

在这里插入图片描述

3. synchronized

Java中的synchronized关键词可以用来同步线程。

synchronized被编译后会生成monitorenter和monitorexit两个字节码指令。依赖这两个字节码指令来进行线程同步。

Monitor原理

monitor依赖于操作系统的mutex lock来实现的。

Java线程实际上是对操作系统线程的映射。所以每当挂起或者唤醒一个线程都要切换操作系统内核态。这种操作是比较重量级的。在一些情况下甚至切换时间本身将会超出线程执行任务的时间。这样的话,使用synchronized将会对程序的性能产生很严重的影响。

四种锁状态的由来

但是从Java6开始,synchronized进行了优化,引入了偏向锁、轻量级锁,所以锁总共有四种状态。从低到高分别是无锁、偏向锁、轻量级锁、重量级锁。这就分别对应了Mark Word中的四种状态。

需要注意的是锁只能升级不能降级。

在这里插入图片描述

4. 锁的4种状态

4.1 无锁

没有对资源进行锁定。所有线程都可以访问到同一资源。

这会出现两种情况:

  1. 某个对象不会出现在多线程环境下,或者说即使出现在了多线程环境下也不会出现竞争的情况。那么确实无需对这个对象进行任何保护,直接让他给任何线程随意调用即可。
  2. 资源会被竞争,但是不希望资源被锁定。不过还是想通过一些机制来控制多线程。

CAS(Compare and Swap)

如果有多个线程想要修改一个值,我们不通过锁定资源的方式而是通过其他方式来限制同时只有一个线程能够修改成功,而其他修改失败的线程将会不断重试直到修改成功。

CAS在操作系统中通过一条指令来实现,所以它就可以保证原子性。通过诸如CAS这种方式,我们可以进行无锁编程。

4.2 偏向锁

假如一个对象被加锁了,但在实际运行时只有一个线程会获取这个对象锁。那么我们最理想的方式就是不通过线程切换,也不要通过CAS来获得锁。

因为这样多多少少还是会耗费一些资源。我们设想的是最好对象能够认识这个线程。

只要这个线程过来,那么对象就直接把锁交出去。我们就可以认为这个对象偏爱这个线程,所以被称为偏向锁。

实现原理

在这里插入图片描述
在Mark Word中,当锁标志位是01时,那么判断倒数第三个bit是否为1。

如果是1,那么代表当前对象的锁状态为偏向锁。否则则为无锁。

如果当前对象的锁状态为偏向锁,于是再去读Mark Word的前23个bit,这23个bit的值就是线程ID。通过线程ID来确认当前想要获得对象锁的这个线程是不是老顾客。

假如情况发生了变化,对象发现目前不只有一个线程而是有多个线程正在竞争锁,那么偏向锁将会升级为轻量级锁。

当锁的状态还是偏向锁时,是通过Mark Word中的线程ID来找到占有这个锁的线程。

那么当锁的状态升级到轻量级锁时,如何判断线程和锁之间的关系呢

4.3 轻量级锁

当一个线程想要获得某个对象的锁时,假如看到锁标志位为00那么就知道它是轻量级锁。

如何判断线程和锁之间的绑定关系

将前30个bit变为指向线程栈中锁记录的指针。

当一个线程想要获得某个对象的锁时,假如看到锁标志位为00,那么就知道它是轻量级锁。

这时线程会在自己的虚拟机栈中开辟一块被称为Lock Record的空间(线程私有的)。

Lock Record中存放的是对象头中的Mark Word的副本以及owner指针。

线程通过CAS去尝试获取锁。一旦获得那么将会复制该对象头中的Mark Word到Lock Record中。并且将Lock Record中的owner指针指向该对象。
另一方面,对象的Mark Word的前30个bit将会生成一个指针指向线程虚拟机栈中的Lock Record。

这样一来,就实现了线程和对象锁的绑定。他们就互相知道了对方的存在。

在这里插入图片描述

这样这个对象就已经被锁定了,获取这个对象锁的线程就可以去执行一些任务。

在这里插入图片描述
这时候万一有其他线程也想要获取这个对象,此时其他的线程将会自旋等待。

自旋

可以理解为轮询。线程自己在不断地循环去尝试着看一下目标对象的锁有没有被释放。如果释放了,那么就去获取。如果没有释放,那么就进入下一个循环。

这种方式区别于被操作系统挂起阻塞,因为如果对象的锁很快就会被释放的话,自旋就不需要进行系统中断和现场恢复。所以它的效率更高。

自旋相当于CPU在空转。如果长时间自旋将会浪费CPU资源,于是出现了一种叫做“适应性自旋”的优化。

简单来说,就是自旋的时间不再固定,而是由上一次在同一个锁上的自旋时间以及锁状态,这两个条件进行决定的。

举个例子,比如说在同一个锁上,当前正在自旋等待的线程刚刚已经成功获得过锁。但是锁目前是被其他线程占用。那么虚拟机就会认为这次自旋也很有可能会再次成功。进而它将允许更长的自旋时间。这就是适应性自旋。

假如此时有一个线程正在进行自旋,那么这个线程将会进行等待。如果同时有多个线程想要获得这个对象锁。也就是说一旦自旋等待的线程超过1个,那么轻量级锁将会升级为重量级锁。

在这里插入图片描述

4.4 重量级锁

需要通过Monitor来对线程进行控制。

此时将会完全锁定资源,对线程的管控也最为严格。

5. 总结

可以通过Synchronized来同步线程。

四种锁的状态以及实现方式等。


在这里插入图片描述

参考资料:【Java并发】月薪30K必须知道的Java锁机制

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

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

相关文章

【计算机视觉·OpenCV】使用Haar+Cascade实现人脸检测

前言 人脸检测的目标是找出图像中所有的人脸对应的位置,算法的输出是人脸的外接矩形在图像中的坐标。使用 haar 特征和 cascade 检测器进行人脸检测是一种传统的方式,下面将给出利用 OpenCV 中的 haarcascade 进行人脸检测的代码。 程序流程 代码 impo…

摩兽Pesgo plus首发爆卖,全网关注度破亿!中国潮玩跨骑电自浪潮已至?

2023年4月11日,TROMOX摩兽圆满举办了“跨骑潮电,大有所玩”Pesgo plus新品发布会。发布会在抖音、天猫、视频号平台进行了同步直播并开启线上预定。发布会直播当晚,摩兽Pesgo plus即狂揽线上订单,全网各大平台相关话题累计热度已破…

XXL-JOB分布式任务调度平台详细介绍

一、概述 在平时的业务场景中,经常有一些场景需要使用定时任务,比如: 时间驱动的场景:某个时间点发送优惠券,发送短信等等。 批量处理数据:批量统计上个月的账单,统计上个月销售数据等等。 固…

用SQL语句操作oracle数据库--数据查询(上篇)

SQL操作Oracle数据库进行数据查询 Oracle 数据库是业界领先的关系型数据库管理系统之一,广泛应用于企业级应用和数据仓库等场景中。本篇博客将介绍如何使用 SQL 语句对 Oracle 数据库进行数据查询操作。 1.连接到数据库 在开始查询之前,需要使用合适的…

素材管理系统概念导入

引言 由于工作上的调整安排,有幸参加营销素材管理系统的产品建设工作中,营销宣传领域一直是我的知识盲区,所以素材管理系统的产品建设对我来说是个富有挑战性的工作,在这过程中,我也秉持着“好记性不如烂笔头”的原则&…

Golang每日一练(leetDay0033) 二叉树专题(2)

目录 97. 交错字符串 Interleaving String 🌟🌟 98. 验证二叉搜索树 Validate Binary Search Tree 🌟🌟 99. 恢复二叉搜索树 Recover Binary Search Tree 🌟🌟 🌟 每日一练刷题专栏 &am…

中国人工智能企业CIMCAI世界前三大船公司落地,智能船公司产品20秒AI自动验箱,箱信息箱况+精确地点报备智慧港航中国人工智能企业

中国人工智能企业CIMCAI世界前三大船公司落地,智能船公司产品20秒AI自动验箱,箱信息箱况精确地点报备智慧港航。小程序全时全域自动化箱况检测信息识别,CIMCAI全球领先新一代集装箱管理方案,人工智能AI自动化箱信息识别箱况检测地…

Python 小型项目大全 21~25

二十一、DNA 可视化 原文:http://inventwithpython.com/bigbookpython/project21.html 脱氧核糖核酸是一种微小的分子,存在于我们身体的每个细胞中,包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构:鸟嘌呤、…

【跟着陈七一起学C语言】今天总结:C语言的函数相关知识

友情链接:专栏地址 知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的错误&#x…

太阳能电池板AI视觉检测:不良品全程阻断,高效助力光伏扩产

2022年,面对复杂严峻的国内外形势,我国光伏行业依然实现高速增长,多晶硅、硅片、电池片、组件产量稳居全球首位。2023年以来,扩产项目已多点开花。光伏装机量天花板将不断提升,分布式电站占比也将逐年上升。中国光伏行…

4月软件测试面试太难,吃透这份软件测试面试笔记后,成功跳槽涨薪30K

4 月开始,生活工作渐渐步入正轨,但金三银四却没有往年顺利。昨天跟一位高级架构师的前辈聊天时,聊到今年的面试。有两个感受,一个是今年面邀的次数比往年要低不少,再一个就是很多面试者准备明显不足。不少候选人能力其…

python学籍管理系统

1,创建登陆的首页面,且封装起来。LoginPage.py import tkinter as tk#导入tk模块 from tkinter import messagebox#导入消息提示模块 from tkinter import messagebox from db import db #导入数据库db class LoginPage:#把整个登陆页面创建一个class类…

搭建自己的饥荒Don‘t Starve服务器-饥荒Don‘t Starve开服教程

前言 饥荒这个游戏,虽然首发于2016年,但是贵在好玩呀。和Minecraft一样,可玩性很高,并且有很多mods,最近和小伙伴玩的过程中,就想着搭建一个服务器,方便在主机玩家不在线时候,也可以…

Linux软件安装---Tomcat安装

安装Tomcat 操作步骤: 使用xftp上传工具将tomcat的 二进制发布包上传到Linux解压安装包,命令为tar -zxvf apache-tomcat*** -C /usr/local进入Tomcat的bin的启动目录,命令为sh startup.sh或者./startup.sh 验证Tomcat启动是否成功&#xff0…

LeetCode:376. 摆动序列——说什么贪心和动规~

🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱376. 摆动序列 题目描述:如果连续数字之间的差严格地在正数和…

Python 小型项目大全 46~50

# 四十六、百万骰子投掷统计模拟器 原文:http://inventwithpython.com/bigbookpython/project46.html 当你掷出两个六面骰子时,有 17%的机会掷出 7。这比掷出 2 的几率好得多:只有 3%。这是因为只有一种掷骰子的组合给你 2(当两个…

「 分布式技术 」一致性哈希算法(Hash)详解

「 分布式技术 」一致性哈希算法(Hash)详解 参考&鸣谢 一致性 Hash 算法原理总结 kylinkzhang,腾讯 CSIG 后台开发工程师 什么是一致性哈希? xiaolinCoding 文章目录「 分布式技术 」一致性哈希算法(Hash&#xff…

imagenet val 按类别分类

前言 有时候想看imagenet下某个类别的效果,但它又没划分… 之前看了这篇文章将ImageNet的验证集val数据分类到不同文件夹中,但不是很清楚那代码。 本文基于它的代码去做更改 把这个下下来 https://raw.githubusercontent.com/soumith/imagenetloader.…

ChatGPT 有哪些神奇的使用方式?

在遇到 ChatGPT之前,我很难想象,仅仅不到30s就能做出一个PPT。 而且对于小白来说,这个PPT绝对是「有水准、能拿得出手」的那种。 下面就是我用ChatGPTMindShow做的一套以分享短视频玩法为主题的 PPT,我挑几页大家看一下。 上面这…

10.Java面向对象----继承

Java面向对象—继承 面向对象简称 OO(Object Oriented),20 世纪 80 年代以后,有了面向对象分析(OOA)、 面向对象设计(OOD)、面向对象程序设计(OOP)等新的系统…