news 2026/8/27 12:02:04

简单讲解Java中的synchronized

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单讲解Java中的synchronized

1. 为什么需要 synchronized?

在多线程环境下,多个线程可能同时访问和修改共享资源,导致数据不一致的问题。

例如:两个线程同时对同一个银行账户余额进行“取款”操作,可能因为操作的非原子性(读-改-写)导致最终结果错误。

synchronized的作用就是保证同一时刻最多只有一个线程执行被它修饰的代码块或方法,从而保证线程安全。


2. synchronized 的三种使用方式

使用方式锁对象作用范围
修饰实例方法当前实例对象this整个方法体
修饰静态方法当前类的Class对象整个方法体
修饰代码块指定的任意对象代码块内的语句

2.1 修饰实例方法 -- 锁对象是整个 this

public class Counter { private int count = 0; public synchronized void increment() { // 锁住 this count++; } }

2.2 修饰静态方法 -- 锁对象是整个类

public class Counter { private static int count = 0; public static synchronized void increment() { // 锁住 Counter.class count++; } }

2.3 修饰代码块(最灵活)-- 锁对象是lock,细粒度锁,只锁这一个特定的锁对象

//只有显式写上 synchronized(lock)的代码块才会排队。其他方法(包括synchronized方法)完全不受影响,可以并行执行。public class Counter { private int count = 0; private final Object lock = new Object(); public void increment() { synchronized (lock) { // 锁住 lock 对象 count++; } } }

3. 锁的是什么?(核心要点)

  • synchronized 不是锁代码,而是锁对象

  • 同一时刻,同一个锁对象只能被一个线程持有。

  • 不同锁对象之间互不干扰。

示例说明:

public class Example { public synchronized void methodA() {} // 锁 this public synchronized void methodB() {} // 锁 this(同一个锁) public static synchronized void methodC() {} // 锁 Class }
  • 线程1 执行methodA()时,线程2 不能执行methodB()(因为锁是同一个this,如果是不同的“this”,则两个方法并不会相互影响)。

  • 但线程2 可以执行methodC()(因为锁是Class,不同锁对象)。


4. 底层实现原理(JVM层面)

  • 监视器锁(Monitor):每个Java对象都有一个内部锁(Monitor)。synchronized本质就是获取/释放这个Monitor。

  • 字节码指令

    • 同步代码块:monitorenter进入,monitorexit退出(可能有多个退出路径)。

    • 同步方法:通过方法表的ACC_SYNCHRONIZED标志隐式实现。

  • 锁升级机制(JDK 1.6+ 优化):无锁 → 偏向锁 → 轻量级锁 → 重量级锁(自旋、自适应自旋、锁粗化、锁消除等优化)。


5. 与 volatile 的区别

特性synchronizedvolatile
原子性✅ 保证 (要么全做,要么全不做)❌ 不保证
可见性✅ 保证(解锁前刷新到主存,改了就得让人看见)✅ 保证
有序性✅ 保证(同一时刻单线程执行,代码按顺序执行,不被重排)✅ 保证(禁止指令重排序)
是否阻塞是(竞争失败会阻塞,获取不到锁时,线程是等待还是放弃)

简单记:volatile解决可见性,synchronized解决可见性 + 原子性。


6. 常见误区与注意事项(可以通过AI简单了解)

  1. 锁对象不能是 null,否则抛NullPointerException

  2. 锁对象尽量使用final,避免引用被修改导致锁失效。

  3. 不要用String常量或Integer等包装类作为锁,因为常量池可能导致意外共享锁。

  4. synchronized 是可重入锁,同一个线程可以多次获取同一把锁(避免死锁)。

  5. 过度使用会降低性能,应尽量缩小同步范围。


7. 简单示例:线程安全的计数器

public class SafeCounter { private int count = 0; private final Object lock = new Object(); public void increment() { synchronized (lock) { count++; } } public int getCount() { synchronized (lock) { return count; } } }

8. 最后一句话:在真正的互联网高并发业务代码中,我们其实很少直接用synchronized处理业务逻辑

synchronized 是 Java 内置的互斥锁,通过锁住对象来保证代码块或方法在并发环境下的原子性、可见性和有序性,是解决线程安全问题最直接、最可靠的手段之一。

  • 分布式场景:现在的服务大多是分布式部署(多台机器),synchronized只能锁单台机器的JVM进程,跨机器无效。我们通常用Redis分布式锁ZooKeeper

  • 单机高性能场景:如果是单机高并发计数器、累加器,我们通常直接用AtomicInteger(CAS无锁)或LongAdder,性能比synchronized高得多。

  • 需要等待/超时/中断的场景:我们会用ReentrantLock(因为它支持尝试加锁、超时等待、可中断),而synchronized不支持这些高级功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 11:58:59

WorldCup Arena:无泄漏的前瞻性LLM锦标赛评测框架

这次我们来看一个不太一样的 LLM 评估项目:WorldCup Arena。它把大模型评测做成了持续进行的“世界杯”锦标赛,模型要像球队一样实时对抗、现场作答,评测题目在设计时还没有出现。换句话说,这不是又一套静态 benchmark&#xff0c…

作者头像 李华
网站建设 2026/8/27 11:58:23

Coze+Dify工作流实战:从在线验证到本地部署与API封装

这次我们来看一个职场向 AI 落地组合:Coze Dify 工作流。很多人纠结这两个平台到底该选哪个,其实它们不是二选一的关系。Coze(扣子)是字节跳动推出的 AI 智能体开发平台,走的是在线 SaaS 路线,胜在开箱即用…

作者头像 李华
网站建设 2026/8/27 11:58:22

java学习过程中遇到的问题

//打印菱形,分为两部分:正等腰三角形,倒等腰三角形 public static void main(String[] args) {Scanner sc new Scanner(System.in);System.out.println("请输入奇数:");int num sc.nextInt();if (num % 2 0) {return;}int mid num / 2;//第一部分:正等腰三角形--…

作者头像 李华
网站建设 2026/8/27 11:57:02

Grasshopper参数化曲面AI着色:从颜色映射到自动化配色

在 Rhino 里完成一个复杂曲面之后,最容易被低估的一步是表达。曲面本身只有几何信息,没有材质、没有颜色、也没有语义;一旦需要把建筑表皮分层、产品渐变、数据可视化结果或 3D 打印样件涂上颜色,手动贴图很快就会失控。Grasshopp…

作者头像 李华
网站建设 2026/8/27 11:56:10

企业级AI Agent三层权限体系:分级授权、凭证隔离与签名许可

AI Agent 已经从“能聊天的玩具”变成了“能干活的下属”。但在企业环境里,引入 Agent 的真实障碍,往往不是模型能力不够、不是推理成本太高,而是那个所有人都在回避的问题: 你凭什么让一个不可完全预测的系统,握有真…

作者头像 李华
网站建设 2026/8/27 11:56:02

Khadas VIM3实战:A73 SoC与NVMe SSD的硬核结合

如果你这几年一直在折腾单板电脑,对Khadas这个品牌应该不会陌生。VIM3是Khadas在2019年底推出的旗舰级SBC,核心用的是Amlogic A311D SoC,4颗Cortex-A73大核加2颗Cortex-A53小核,GPU是Mali-G52 MP4,还带了一颗5TOPS算力…

作者头像 李华