0

0

synchronized关键字是做什么用的_Java同步机制详解

P粉602998670

P粉602998670

发布时间:2026-01-03 16:51:07

|

906人浏览过

|

来源于php中文网

原创

synchronized核心作用是让多线程排队访问共享资源,解决原子性、可见性、有序性三大问题;锁对象决定同步范围,需避免死锁与滥用;JDK 1.6后已优化,性能并非瓶颈。

synchronized关键字是做什么用的_java同步机制详解

synchronized 的核心作用是:让多线程「排队访问共享资源」,避免数据错乱、读到脏值或执行结果不可预期。

为什么必须用 synchronized 而不是靠自己加 flag?

boolean isRunning 这类手动标记根本不可靠——它既不能阻止线程同时进入临界区(缺乏互斥),也无法保证修改立刻被其他线程看到(缺乏可见性)。而 synchronized 一次性解决三个问题:

  • 原子性:同一时刻只允许一个线程执行被锁住的代码块
  • 可见性:退出同步块时,所有变量修改强制刷回主内存;进入时清空本地缓存,重新从主内存加载
  • 有序性:隐式插入内存屏障,禁止编译器和 CPU 对临界区内的读写重排序

这三点不是“可选功能”,是 JVM 规范强制保证的,靠手写逻辑无法等效实现。

synchronized(this) 和 synchronized(ClassName.class) 到底锁谁?

锁对象决定了同步范围,选错就等于没锁:

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

  • synchronized(this) 锁的是当前实例对象,不同对象之间完全不干扰。适合保护实例变量(如 private int count
  • synchronized(Counter.class)public static synchronized void inc() 锁的是类对象,所有该类的实例共用一把锁。适合保护静态变量或全局计数器
  • 绝不能写 synchronized(new Object()) —— 每次新建对象,锁对象都不同,等于没加锁
public class Counter {
    private int instanceCount = 0;
    private static int staticCount = 0;

    // ✅ 正确:保护实例变量
    public void incrementInstance() {
        synchronized (this) {
            instanceCount++;
        }
    }

    // ✅ 正确:保护静态变量
    public static void incrementStatic() {
        synchronized (Counter.class) {
            staticCount++;
        }
    }
}

常见死锁场景和怎么绕开?

死锁不是小概率事件,而是锁顺序不一致的必然结果。典型模式:

智谱AI输入法
智谱AI输入法

智谱AI推出的AI语音输入法

下载
  • 线程 A 先锁 lock1 再锁 lock2
  • 线程 B 先锁 lock2 再锁 lock1
  • 两者卡住,互相等待对方释放锁

规避方法只有两条硬规则:

  • 所有线程必须以**相同顺序**获取多个锁(比如永远先 lock1lock2
  • 尽量用「一个锁」解决问题;实在需要多个锁,优先考虑 ReentrantLock.tryLock(timeout) 带超时的尝试获取,失败就释放已持锁并重试

性能真那么差?JDK 1.6 之后的优化你得知道

很多人还在用“synchronized 是重量级锁”当口头禅,但现实是:

  • 偏向锁(默认开启):无竞争时几乎零成本,只在对象头 mark word 记个线程 ID
  • 轻量级锁:竞争不激烈时用 CAS 替代系统互斥量,避免进内核态
  • 锁膨胀是逐级触发的——只有真正高并发争抢才会升级为重量级锁
  • 除非你压测发现 synchronized 成为瓶颈,否则别急着换 ReentrantLock;后者更灵活,但也更易出错(比如忘记 unlock()

真正影响性能的,往往不是锁本身,而是同步块里干了太多事——比如在 synchronized 里调远程接口、解析大 JSON、做复杂计算。把耗时操作移出去,比换锁类型管用十倍。

最常被忽略的一点:synchronized 的锁释放是「自动且绝对可靠」的——哪怕方法抛异常、return 中断、甚至 JVM crash(在正常运行路径下),JVM 都会确保 monitorexit 执行。这点比手动管理的锁更安全,也更省心。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

403

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

530

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

308

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

346

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

21

2025.11.30

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

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

193

2023.11.20

string转int
string转int

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

313

2023.08.02

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

194

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.2万人学习

C# 教程
C# 教程

共94课时 | 5.9万人学习

Java 教程
Java 教程

共578课时 | 41.5万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号