synchronized 的使用和特性

synchronized 锁对象

普通方法
synchronized 锁普通方法时,其锁的对象是调用该方法的实例

public synchronized void method() {  // 方法体  
}  

静态方法
静态方法的锁对象是所属的 class,全局只有一个。

public static synchronized void staticMethod() {  // 方法体  
}  

同步代码块
锁对象为括号内的指定对象。

synchronized(this) {  // 代码块  
}  

synchronized 特性

有序性
读读,读写,写读,写写互斥。

可见性
可见性是指多个线程访问一个资源时,该资源的状态,值等对于其他线程都是可见的。synchronized 和 volatile 都具有可见性,其中 synchronized 对一个类或对象加锁时,一个线程如果要访问该累或对象必须先获得它的锁。这个锁的状态对于其他任何线程都是可见的,并且在释放锁之前会将对变量的修改刷新到共享内存中,保证资源变量的可见性。

原子性
原子性指的是同一时间只有一个线程去执行代码,该操作是不能被其他线程打断的,那么就具备了原子性。

synchronized的原子性本质上是线程互斥保证的原子性。

可重入性
同一线程在持有锁的情况下,可多次获取同一锁而不会导致死锁或阻塞其他线程。这种机制通过维护锁的持有计数器实现,当线程首次获取锁时计数器设为1,每次重入增加计数,释放时减少计数,直到归零才释放锁。

synchronized 锁升级的对象头内容:
在这里插入图片描述

偏向锁的意义和使用前提

偏向锁就是在运行过程中,对象的锁偏向某个线程。即在开启偏向锁机制的情况下,某个线程获得锁,当该线程下次再想要获得锁时,不需要重新申请获得锁(即忽略synchronized关键词),直接就可以执行同步代码,比较适合竞争较少的情况。

JDK 1.8 下加锁会默认开启偏向锁。但是它在应用程序启动几秒后才会开启,是存在延迟启动的情况。因此可能在打印输出加锁时的信息会发现不符合偏向锁的锁标志。

当我们开启了偏向锁,并且没有延迟开启的时候,新创建的对象的 mark word 默认就是偏向锁状态的 markWord,只不过这个时候,因为没有线程争抢锁,除了我们的锁标志位和是否为偏向锁标志位,其他都是 0

延迟的关闭和偏向锁的关闭

延迟是可以关闭的。可以给 JVM 设置参数:-XX:BiasedLockingStartupDelay=0 来关闭延迟。
如果希望关闭偏向锁:-XX:-UseBiasedLocking=false

偏向锁细节

无锁状态下的 MarkWord 标志(看第一行的二进制数字):
01 表示偏向锁,是由于开启偏向锁且没有延迟开启的情况下会显示的,但是此时并没有线程争夺锁。因此其他位置都是 0 ,仅仅是锁标志位和是否为偏向锁标志位有变化。
在这里插入图片描述
线程加上偏向锁后:
根据上图,偏向锁加上了后会有标识线程 ID,Epoch 等信息,因此不全是 0 。
在这里插入图片描述

如果我们在加锁前调用 hashcode 方法,会导致后续加锁后变为轻量级锁。

原理:

  • 被加锁的对象,没有真正调用或者隐式的调用(比如使用 HashMap 放入当前对象,会调用 HashCode 方法)父类 Object 的 hashCode 方法,如果一旦调用了 hashCode 方法,对象头里需要有一个存储该 hashCode 值的位置。但是我们可以从上图中看到,偏向锁中并没有地方进行 MarkWord 的保存,只有轻量级锁才会有。

  • 为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID(对象头:存储线程 ID,栈帧的锁记录中:线程有自己的栈帧,LOCK RECORD: 存储当前线程 ID),以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。(是否是当前线程的偏向锁是通过ID来匹配的)

  • 如果测试成功,表示线程已经获得了锁。

  • 如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁):如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程(CAS 竞争,替换线程 ID)

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

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

相关文章

Gin Web 层集成 Viper 配置文件和 Zap 日志文件指南(下)

在微服务架构中,Gin 常被用作 Web 层框架,而 Viper 用于管理配置文件,Zap 则提供高性能的日志记录功能。下面将详细介绍如何在 Gin Web 层集成 Viper 配置文件和 Zap 日志文件。 1. 项目概述 假设我们有一个基于 Go 语言的微服务项目&#…

IoTDB:专为物联网场景设计的高性能时序数据库

什么是IoTDB?IoTDB(Internet of Things Database)是一款开源的时序数据库管理系统,专为物联网(IoT)场景设计,由清华大学软件学院团队自研,天谋科技团队负责维护。它针对物联网数据的…

[netty5: MessageAggregator HttpObjectAggregator]-源码解析

在阅读这篇文章前,推荐先阅读 [netty5: ByteToMessageCodec & MessageToByteEncoder & ByteToMessageDecoder]-源码分析[netty5: HttpObject]-源码解析 100-continue 100-continue 是 HTTP/1.1 协议中的一种机制,用于客户端在发送大体积请求体…

前端学习1--行内元素 vs 块级元素(基础概念+案例实操)

一、内外边距学习:(1)简单理解:padding为内边距。padding不会影响元素的位置,只会调整元素的内容(文字)与边框之间的间距。margin为外边距。margin会影响元素在流式布局中的位置,改变…

Express + mysql2 + jwt 实现简单的登录鉴权

目前项目中使用Express 实现简单API功能,需要提供一套登录鉴权方案。这边是API侧实现 相关路由的登录鉴权。大体思路:就是,登录接口中通过jwt加密 token返回前端,前端其他接口把加密好的放入请求头Authorization中。中间件通过请求…

ReAct (Reason and Act) OR 强化学习(Reinforcement Learning, RL)

这个问题触及了现代AI智能体(Agent)构建的两种核心思想。 简单来说,ReAct 是一种“调用专家”的模式,而强化学习 (RL) 是一种“从零试错”的模式。 为了让你更清晰地理解,我们从一个生动的比喻开始,然后进行…

iTwinjs 4.10-4.11 更新

撤销更改 目前,撤销一个有缺陷的变更集的唯一方法是从 iModel Hub 中移除它,这可能会导致许多副作用(无法撤销)。一个更好的方法是在时间线中撤销变更集,并将其作为新的变更集引入。尽管这种方法仍然具有侵入性&#…

【CSS-15】深入理解CSS transition-duration:掌握过渡动画的时长控制

在现代网页设计中,平滑的过渡效果是提升用户体验的关键因素之一。CSS transitions 为我们提供了一种简单而强大的方式来实现元素在不同状态之间的平滑过渡,而 transition-duration 属性则是控制这些过渡效果时长的核心工具。本文将全面探讨 transition-d…

mysql-笔记

1. 安装mysql # 使用brew安装 brew install mysql# 查看是否安装成功 mysql -V 相关文档: mac:macOS下MySQL 8.0 安装与配置教程 - KenTalk - 博客园 Linux安装:linux安装mysql客户端_linux mysql 客户端-CSDN博客 2. 启动mysql 每次使…

Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践

Spring Boot启动优化7板斧:砍掉70%启动时间的魔鬼实践1. 延迟初始化:按需加载的智慧2. 组件扫描精准打击:告别无差别扫描3. JVM参数调优:启动加速的隐藏开关4. 自动配置瘦身:砍掉Spring Boot的"赘肉"5. 类加…

从0开始学习计算机视觉--Day08--卷积神经网络

之前我们提到,神经网络是通过全连接层对输入做降维处理,将输入的向量通过矩阵和激活函数进行降维,在神经元上输出激活值。而卷积神经网络中,用卷积层代替了全连接层。 不同的是,这里的输入不再需要降维,而…

解决阿里云ubuntu内存溢出导致vps死机无法访问 - 永久性增加ubuntu的swap空间 - 阿里云Linux实例内存溢出(OOM)问题修复方案

效果图报错通过对实例当前截屏的分析发现,实例因 Linux实例内存空间不足,导致操作系统出现内存溢出(OOM) 无法正常启动。请您根据 Code:1684829582,在文档中查询该问题对应的修复方案,并通过VNC…

Serverless JManus: 企业生产级通用智能体运行时

作者:丛霄、陆龟 概述:本文介绍如何使用 JManus 框架构建通用智能体应用,部署并运行在 Serverless 运行时,构建企业级高可用智能体应用的实践经验。基于阿里云 Serverless 应用引擎SAE 运行稳定高可用的智能体应用, 基…

MySQL的数据目录

导读:根据前面的所学知识,我们知道了InnoDB存储引擎存储数据的数据结构、存储过程,而被组织好的数据则被存储在操作系统的磁盘上,当我们在对表数据进行增删改查时,其实就是InnoDB存储引擎与磁盘的交互。此外&#xff0…

Web前端开发: :has功能性伪类选择器

:has功能性伪类选择器::has() 是 CSS 中的一个功能性伪类选择器,它允许开发者根据元素的后代元素、兄弟元素或后续元素的存在或状态来选择目标元素。它本质上是一个“父选择器”或“关系选择器”,解决了 CSS 长期以来无法根据子元素反向选择父元素的痛点…

深度学习8(梯度下降算法改进2)

目录 RMSProp 算法 Adam算法 学习率衰减 RMSProp 算法 RMSProp(Root Mean Square Prop)算法是在对梯度进行指数加权平均的基础上,引入平方和平方根。 其中e是一个非常小的数,防止分母太小导致不稳定,当 dw 或 db 较大时,(du)2,(db)2会较大&…

JAVA面试宝典 -《网络编程核心:NIO 与 Netty 线程模型详解》

网络编程核心:NIO 与 Netty 线程模型详解 文章目录网络编程核心:NIO 与 Netty 线程模型详解一、传统 BIO 模型:排队买奶茶的阻塞模式 🥤1.1 专业解释1.2 简单点比喻1.3 简单示例二、NIO 模型:智能叫号餐厅系统 &#x…

蓝桥杯 第十六届(2025)真题思路复盘解析

本文以洛谷平台所提供的题目描述及评测数据为基础进行讲解。 前言:这是本人的蓝桥杯试卷,大概排省一前40%的位置,实际上这届题目偏难,我没有做出太多的有效得分。我把当时的思路和现在学习的思路都复盘进来,希望给大家…

兰顿蚂蚁路径lua测试

兰顿蚂蚁local p0 local x,y,z0,7,0 local function add() local result,id Block:getBlockID(x,y,z)if id1 thenBlock:destroyBlock(x,y,z,false) pp90 elseBlock:setBlockAll(x,y,z,1,0) pp-90 end x,zx-math.floor(0.5math.sin(math.rad(p))),z-math.floor(0.5math.cos(m…

【Axure RP】什么是Axure?Axure可以用来做什么?

【Axure RP】什么是Axure?Axure可以用来做什么? 目录【Axure RP】什么是Axure?Axure可以用来做什么?Axure RP简介Axure RP 是什么?Axure RP核心功能和应用场景Axure RP简介 Axure RP 是什么? Axure RP 是一…