大厂面试真题-说说synchronized的锁升级过程

在Java中,synchronized关键字是实现线程同步的一种方式,但其性能受到锁开销的影响。为了减少锁带来的性能损失,Java虚拟机(JVM)设计了一套锁升级机制。这一机制使得锁可以从无锁状态逐渐升级至重量级锁,以根据竞争程度动态调整锁策略,达到最佳性能平衡。以下是synchronized锁升级的详细过程:

一、无锁状态

  • 在对象创建之初,它处于无锁状态,没有任何锁标志位被设置。此时,对象可以被任何线程自由访问,因为没有线程试图获取锁。

二、偏向锁状态

  • 当第一个线程尝试获取synchronized锁时,JVM会将对象头标记为偏向锁状态,并在对象头中记录获取锁的线程ID。
  • 如果后续访问仍然是由这个线程发起的,它将无需进行额外的同步检查,即可直接访问对象,因为锁已经偏向于这个线程。这种优化减少了单一线程访问同一对象的开销。
  • 然而,如果其他线程尝试访问这个同步块,偏向锁将被撤销,并进入轻量级锁状态。撤销时会有一定的开销,包括检查偏向锁标识、CAS操作尝试清除偏向锁等。

三、轻量级锁状态

  • 当第二个线程尝试获取同一个对象的锁时,偏向锁会被撤销,对象变为轻量级锁状态。
  • 轻量级锁使用了ThreadLocal(此处指JVM内部为每个线程维护的锁记录,而非java.lang.ThreadLocal类)变量来存储锁记录,而不是直接使用操作系统的互斥锁。
  • 线程会在自己的栈帧中创建一个称为Lock Record的空间,用于存储锁的Mark Word的拷贝。然后通过CAS操作尝试将对象头的Mark Word替换为指向Lock Record的指针。
    • 如果成功,线程获得锁。
    • 如果失败,则说明存在竞争,线程将进入自旋状态,不断尝试CAS操作直到成功或达到自旋上限(JDK1.6前默认10次,之后采用自适应自旋,JVM自动调整)。
  • 自旋锁是线程在获取锁的过程中,不会去阻塞线程,而是通过循环获取锁。这避免了立即进入重量级锁状态,从而减少了线程阻塞和上下文切换的开销。但需要注意的是,如果自旋次数过多仍然没有获取到锁,会消耗较多的CPU资源。

四、重量级锁状态

  • 如果自旋超过一定次数(自旋阈值)仍未获得锁,轻量级锁将升级为重量级锁。
  • 重量级锁涉及操作系统层面的互斥锁(如Linux的mutex),可能导致线程阻塞和上下文切换,从而增加了性能开销。
  • 一旦升级为重量级锁,所有后续试图获取锁的线程都将被阻塞,直到锁被释放。被阻塞的线程会进入等待队列,而持有锁的线程执行完毕后,会唤醒队列中的下一个等待线程。

五、锁升级的特点

  • 锁升级的过程是不可逆的。一旦升级到重量级锁,就不会再降级回轻量级锁或偏向锁。
  • 锁升级是为了在不同的并发压力下优化锁的性能。在低竞争情况下,偏向锁和轻量级锁能够减少不必要的开销;而在高竞争情况下,重量级锁能够确保线程间的正确同步。

综上所述,synchronized的锁升级过程是一个从低开销到高开销、从非阻塞到阻塞的逐渐升级过程。这一机制旨在根据竞争程度动态调整锁策略,以达到最佳性能平衡。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

破解反编译:使用 ClassFinal 保护你的SpringBoot代码

在当今数字化时代,保护源代码的安全性变得愈发重要。无论是企业的核心算法还是独特的业务逻辑,代码一旦暴露,便可能导致竞争优势的丧失和商业机密的泄露。因此,在使用 Java 和 Spring Boot 开发项目时,理解从源代码到可…

websocket连接异常报错1006

目录: 1、问题现象2、问题原因3、解决方案 1、问题现象 WebSocket状态码的作用: 在WebSocket协议中,状态码用于表示连接状态和错误信息。通过状态码,我们可以快速判断连接是否成功,以及出现错误时的原因。常见的WebSo…

教培机构如何向知识付费转型

在数字化时代,知识付费已成为一股不可忽视的潮流。面对这一趋势,教育培训机构必须积极应对,实现向知识付费的转型,以在新的市场环境中立足。 一、教培机构应明确自身的知识定位。 在知识付费领域,专业性和独特性是关键…

VUE前后端分离毕业设计题目项目有哪些,VUE程序开发常见毕业论文设计推荐

目录 0 为什么选择Vue.js 1 Vue.js 的主要特点 2 前后端分离毕业设计项目推荐 3 后端推荐 4 总结 0 为什么选择Vue.js 使用Vue.js开发计算机毕业设计是一个很好的选择,因为它不仅具有现代前端框架的所有优点,还能让你专注于构建高性能、高可用性的W…

Matlab实现白鲸优化算法优化回声状态网络模型 (BWO-ESN)(附源码)

目录 1.内容介绍 2部分代码 3.实验结果 4.内容获取 1内容介绍 2部分代码 %% 清空环境变量 warning off % 关闭报警信息 close all % 关闭开启的图窗 clear % 清空变量 clc % 清空命令行 tic load bwand %%…

CC2530定时器1中断实现定时1-3

源码 #include "iocc2530.h"//引用CC2530头文件int t1_Count0; //定时器1溢出次数计数void Init_Led(void){ /*******************LED1初始化部分******************/P1SEL &~ 0x01; //设置P1_0口为通用I/O口P1DIR | 0x01; //设置P1_0口为输出口P…

软考越来越难了,2024年软考究竟还值不值得考?

最近不少同学沟通,聊到软考现在越来越难了,考了两三次都没过,也有不少新同学咨询软考考试的一些福利政策,投入大量的物力,财力,精力,那么到底软考值不值得考呢? 01 / 关于软考 软考…

Leetcode 10. 正则表达式匹配

1.题目基本信息 1.1.题目描述 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分…

k8s的控制节点不能访问node节点容器的ip地址

master控制node服务器添加容器后,访问不了该node服务器容器的ip,只能在node服务器访问 排查后发现是k8s的master服务器和node节点的网址网段和k8s初始化时提示的ip网段不一致 我之前是192.168.137.50, 实际上master主机期望的是192.168.1.50 解决方案: 1.删除服务器后重建ma…

python爬虫 - 进阶requests模块

🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、SSL证书问题 (一)跳过 SSL 证书验证 &#xff0…

Vue3中提到的Tree-shaking

我们知道,Vue3中提到一个叫Tree-shaking的东西,其实也并不是一个新的东西,有人称之为"摇树优化",什么意思? 按照作者的原话解释,Tree-shaking其实就是:把无用的模块进行“剪枝”&…

【Linux】进程间通信——System V消息队列和信号量

一、消息队列 1.1 概念 进程间通信的原理是让不同进程看到同一份资源,资源种类的不同就决定了通信方式的差异。如果用管道通信,则资源是文件缓冲区;如果用共享内存,则资源是内存块 消息队列是由操作系统提供的资源,…

postman自动化实战总结

Postman实战总结 简介 本次实战内容主要包括如下几点: l 背景介绍 l Postman使用,侧重于自动化实现,基础使用不做介绍 l 可视化Newman介绍 l 框架特色 l 实战中的坑 背景 随着国内软件技术的高速发展,越来越多的手工测试…

解决谷歌浏览器在安卓手机上的常见问题

在使用安卓手机浏览网页时,谷歌浏览器无疑是许多用户的首选。然而,在使用过程中,用户可能会遇到一些常见问题,如搜索图片困难、缓存积累过多导致浏览器卡顿,以及无法下载视频等。本文将针对这些问题,提供详…

【Linux】详解Linux下的工具(内含yum指令和vim指令)

文章目录 前言1. Linux下软件安装的方式2. yum2.1 软件下载的小知识2.2 在自己的Linux系统下验证yum源的存在2.3 利用yum指令下载软件2.4 拓展yum源(针对于虚拟机用户) 3. vim编辑器3.1 vim是什么?3.2 如何打开vim3.2 vim各模式下的讲解3.2.1…

【C语言】猜数字小游戏

😂个人主页: 起名字真南 🤣个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 随机数的生成1.1 rand1.2 srand1.3 time1.4 设置随机数范围 2 猜数字游戏实现 前言:我们学习完前面的循环以后可以写一个猜数字小游戏 1 随机数的生成 想要完成…

新生培训 day1 C语言基础 顺序 分支 循环 数组 字符串 函数

比赛地址 b牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ C语言数据类型 字符 整型数 int 2e9 long long 9e18 浮点数 代码示例 /** Author: Dduo * Date: 2024-10-8* Description: 新生培训day1 */ #include <stdio.h>int main() {// 定义变量in…

QT-空窗口主窗口对话框

1. QMainWindow QMainWindow 用来创建主窗口 主窗口包含&#xff1a; 标题栏&#xff08;Window title&#xff09;、菜单栏&#xff08;MenuBar&#xff09;、工具栏&#xff08;ToolBar&#xff09;、状态栏&#xff08;StatusBar&#xff09;、停靠部件&#xff08;DockWid…

Ansible学习之ansible-pull命令

想要知道ansible-pull是用来做什么的&#xff0c;就需要了解Ansible的工作模&#xff0c;Ansible的工作模式有两种&#xff1a; push模式 push推送&#xff0c;这是Ansible的默认模式&#xff0c;在主控机上编排好playbook文件&#xff0c;push到远程主机上来执行。pull模式 p…

RISC-V知识点目录

分支预测 分支预测概述https://blog.csdn.net/zhangshangjie1/article/details/136947089?sharetypeblogdetail&sharerId136947089&sharereferPC&sharesourcezhangshangjie1&spm1011.2480.3001.8118分支指令的方向预测https://blog.csdn.net/zhangshangjie1/a…