讲师中心 微信公众号
AI工具推荐 视频效率加速

在Java中synchronized关键字如何保证线程安全_Java内置锁机制原理解析

雨明吖_1244

雨明吖_1244

发布时间:2026-01-20 12:22:11

|

847人浏览过

|

来源于php中文网

原创

synchronized能防止count++出错,因其将非原子的读-改-写三步强制串行执行,并保证可见性;锁对象不同(this或class)决定阻塞范围;JVM锁升级机制优化低并发性能;同步代码块比同步方法更精准高效。

在java中synchronized关键字如何保证线程安全_java内置锁机制原理解析

为什么 synchronized 能防止 count++ 出错

因为 count++ 不是原子操作,它实际拆成三步:读取当前值 → 加 1 → 写回内存。多个线程同时执行这三步,就可能互相覆盖,导致最终结果比预期少。而 synchronized 强制这些步骤在临界区内串行执行——同一时刻只有一个线程能进入,其他线程必须等锁释放后才能尝试获取。

  • 锁的粒度决定并发能力:锁 this 时,不同实例互不影响;锁 Counter.class 时,所有实例共用一把锁,吞吐量骤降
  • 即使方法抛异常,JVM 也会自动执行 monitorexit 指令释放锁,不会发生“死锁住不放”的情况
  • 它不只是互斥,还附带内存语义:锁释放时强制刷写变量到主内存,锁获取时强制从主内存重读,解决了可见性问题

synchronized(this) 和 synchronized(Counter.class) 的区别在哪

关键看锁对象是谁——决定了哪些线程会互相阻塞。

  • synchronized(this):锁的是当前实例(比如 new Counter()),两个不同实例的同步方法可并行执行
  • synchronized(Counter.class) 或 public static synchronized void inc():锁的是 Counter.class 对象,所有该类的实例共享这把锁,静态方法和 class 锁本质是同一回事
  • 错误示范:synchronized("lock") —— 字符串常量池会复用相同字面量的字符串,导致看似无关的代码意外串行,极易引发隐蔽竞争

锁升级机制如何影响实际性能

HotSpot JVM 并不是一上来就用重量级锁,而是按需升级:无锁 → 偏向锁 → 轻量级锁 → 重量级锁。这意味着低并发场景下几乎没有上下文切换开销。

JavaStoryDevelop
JavaStoryDevelop

你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在

下载
  • 偏向锁适合单线程反复进入同一同步块(如初始化阶段),首次加锁只记录线程 ID,后续无需 CAS
  • 轻量级锁在中等竞争时启用自旋(spin),线程在用户态循环等待,避免进内核态阻塞
  • 一旦自旋失败次数超阈值(默认 10 次),或有多个线程竞争,就会膨胀为重量级锁,此时线程真正挂起,触发 OS 调度,开销明显上升
  • 可通过 JVM 参数 -XX:-UseBiasedLocking 关闭偏向锁(JDK 15+ 默认禁用),适用于高竞争服务端场景

同步代码块比同步方法更值得优先使用

同步方法会锁住整个方法体,哪怕只有几行要保护,其余逻辑也得排队。而同步代码块可以精准包裹临界区,减少锁持有时间,提升并发度。

立即学习“Java免费学习笔记(深入)”;

public void transfer(Account from, Account to, int amount) {
    // 非临界操作:校验、日志等,无需锁
    if (from.getBalance() < amount) throw new InsufficientException();
    
    // 只锁真正需要互斥的部分
    synchronized (from) {
        synchronized (to) {
            from.debit(amount);
            to.credit(amount);
        }
    }
}
  • 注意嵌套锁顺序:始终按固定顺序(如按对象 hashcode 排序)获取多把锁,否则容易死锁
  • 不要用 String、Integer 等常量池对象作锁,它们可能被其他模块无意复用
  • 若需细粒度控制,推荐声明私有 final 锁对象:private final Object lock = new Object();,避免锁被外部误用
锁不是越粗越好,也不是越细越安全——关键是识别出真正的共享状态变更点,并确保所有访问路径都走同一把锁。很多并发 bug 其实源于“以为自己锁住了,其实漏了一处”。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6439

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6084

2023.10.24

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3208

2023.11.20

字符串常量的表示方法
字符串常量的表示方法

字符串常量的表示方法:1、使用引号;2、转义字符;3、多行字符串;4、原始字符串;5、字符串连接;6、字符串字面量和对象;7、编码问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1023

2023.12.26

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1758

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2724

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6084

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5729

2023.11.24

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn