在Java并发编程领域synchronized是最基础、最核心的同步机制之一也是Java开发者必须熟练掌握的知识点。从Java 1.0诞生之初synchronized就作为内置锁存在承担着解决多线程并发安全问题的核心职责——它能够保证同一时刻只有一个线程执行特定代码块避免多线程竞争共享资源导致的数据错乱、线程安全问题。很多开发者对synchronized的认知停留在“加锁关键字”的表层认为它只是“简单加锁、保证原子性”却忽略了其底层复杂的实现原理、锁升级机制、性能优化细节以及与其他并发工具如Lock的区别。事实上synchronized的底层涉及JVM指令、对象头结构、操作系统互斥锁、锁优化偏向锁、轻量级锁、重量级锁等多个核心知识点其进化历程从Java 1.0的重量级锁到Java 1.6的锁升级机制也体现了Java并发性能的不断优化。本文将从“基础认知→底层原理→锁机制演进→使用场景→性能优化→实战案例→面试高频考点→常见误区”八个维度全面、系统、深度地剖析synchronized的核心知识结合JVM源码、字节码解析、实战代码、性能测试帮助读者从底层到应用彻底掌握synchronized的本质理解其锁升级的逻辑、性能差异、适用场景以及在并发编程中的最佳实践。全文总字数超7000字涵盖从基础到进阶的全部核心知识点适合Java初学者、开发工程师、架构师阅读也可作为面试复习、技术复盘的权威参考资料。第一章 基础认知synchronized的核心作用与使用场景在深入底层原理之前我们首先要明确synchronized的核心作用、基本使用方式和适用场景建立对synchronized的基础认知为后续的深度剖析奠定基础。1.1 核心作用解决多线程并发安全问题Java是一门支持多线程的语言多线程能够提高程序的执行效率但同时也会带来并发安全问题——当多个线程同时访问、修改同一个共享资源时由于线程执行的随机性和无序性会导致数据错乱、结果不一致等问题这就是“线程安全问题”。示例线程安全问题演示运行结果分析多次运行该程序最终计数往往小于100000如98765、99321等这就是典型的线程安全问题。原因是count操作并非原子操作它被拆分为三个字节码指令读取共享变量count的值到线程本地内存将本地内存中的count值加1将加1后的值写入共享内存主内存。当多个线程同时执行这三个步骤时会出现“线程交替执行”的情况例如线程A读取count10线程B也读取count10线程A加1后写入count11线程B加1后也写入count11导致两次自增操作只生效一次最终计数小于预期。而synchronized的核心作用就是通过“加锁”的方式保证同一时刻只有一个线程能够执行特定的代码块临界区从而避免多线程并发竞争共享资源解决线程安全问题。给上面的increment方法加上synchronized修饰后运行结果将稳定为100000彻底解决线程安全问题。1.2 核心特性原子性、可见性、有序性synchronized能够解决线程安全问题本质上是因为它同时保证了并发编程的三大核心特性原子性、可见性、有序性这也是synchronized与其他并发工具如volatile的核心区别volatile只能保证可见性和有序性无法保证原子性。1.2.1 原子性原子性是指一个操作或一组操作要么全部执行完毕要么全部不执行中间不会被其他线程打断。synchronized通过“排他锁”机制保证临界区的代码块在同一时刻只有一个线程执行从而确保临界区内的操作具备原子性。例如上面的increment方法加上synchronized后count操作就具备了原子性——线程进入方法时获取锁执行完count操作后释放锁中间不会被其他线程打断从而避免了多线程交替执行导致的数据错乱。注意synchronized保证的是“临界区代码块的原子性”而非单个变量的原子性。如果临界区内包含多个操作这些操作会被当作一个整体具备原子性。1.2.2 可见性可见性是指当一个线程修改了共享变量的值后其他线程能够立即看到该修改后的值。在多线程环境中线程会将共享变量从主内存读取到本地内存工作内存中进行操作操作完成后再写入主内存。如果没有可见性保证线程A修改了共享变量的值后线程B可能仍然读取本地内存中的旧值导致数据不一致。synchronized通过“锁释放-锁获取”的机制保证可见性当线程释放锁时会将本地内存中修改后的共享变量值刷新到主内存当线程获取锁时会清空本地内存中的共享变量值重新从主内存读取最新的值。这样一来任何线程修改了共享变量后其他线程获取锁时都能读取到最新的值从而保证了共享变量的可见性。1.2.3 有序性有序性是指程序执行的顺序按照代码的先后顺序执行避免指令重排序导致的执行顺序混乱。在Java中为了提高程序的执行效率JVM和CPU会对指令进行重排序在不影响单线程执行结果的前提下但重排序会导致多线程环境下的执行顺序混乱从而引发线程安全问题。synchronized通过“排他锁”机制保证有序性由于同一时刻只有一个线程能够执行临界区的代码因此临界区内的代码会按照代码的先后顺序执行不会出现指令重排序的问题。同时synchronized还会禁止“指令重排序”跨越锁的边界——锁释放前的指令不会被重排序到锁释放后锁获取后的指令不会被重排序到锁获取前。1.3 基本使用方式三种加锁场景synchronized在Java中有三种基本使用方式分别对应不同的加锁场景本质上都是对“对象”加锁synchronized的锁是对象锁而非方法锁或代码块锁只是加锁的对象不同。1.3.1 修饰实例方法锁对象为当前实例this当synchronized修饰实例方法时锁的对象是当前类的实例this即每个实例对应一把独立的锁。多个线程访问同一个实例的synchronized实例方法时会相互阻塞但访问不同实例的synchronized实例方法时不会相互阻塞因为锁对象不同。示例补充说明如果创建两个不同的实例两个线程分别访问各自实例的synchronized方法不会相互阻塞因为锁对象是不同的实例this此时两个线程可以同时执行。1.3.2 修饰静态方法锁对象为当前类的Class对象当synchronized修饰静态方法时锁的对象是当前类的Class对象每个类只有一个Class对象全局唯一。无论创建多少个类的实例多个线程访问该类的synchronized静态方法时都会相互阻塞因为锁对象是唯一的Class对象。示例核心结论synchronized静态方法的锁是“类锁”Class对象全局唯一无论多少个实例只要访问该类的synchronized静态方法都会竞争同一把锁而synchronized实例方法的锁是“实例锁”this每个实例一把锁相互独立。1.3.3 修饰代码块锁对象为自定义对象当synchronized修饰代码块时锁的对象是括号中指定的对象可以是this、Class对象也可以是自定义的对象这种方式的灵活性最高能够精准控制加锁的范围避免不必要的锁竞争提高程序性能。常见的锁对象选择锁对象为this与synchronized修饰实例方法的效果一致锁定当前实例锁对象为Class对象与synchronized修饰静态方法的效果一致锁定当前类锁对象为自定义对象锁定指定的对象适用于多线程竞争同一共享资源的场景可实现“细粒度锁”。示例自定义锁对象优势分析通过自定义锁对象实现了“细粒度加锁”——操作count1用lock1操作count2用lock2两个线程可以同时执行increment1和increment2方法不会相互阻塞相比“给整个方法加锁”大幅提高了程序的并发性能。这也是synchronized代码块的核心优势精准控制加锁范围减少锁竞争。1.4 核心注意点新手必看synchronized的锁是“对象锁”无论哪种使用方式本质都是对某个对象加锁锁的竞争只发生在“竞争同一把锁”的线程之间synchronized是“可重入锁”后面会详细讲解即同一个线程可以多次获取同一把锁不会导致死锁synchronized是“非公平锁”后面会详细讲解即线程获取锁的顺序不遵循“先到先得”可能存在线程饥饿的情况synchronized不能修饰构造方法语法错误因为构造方法本身是创建实例的过程此时实例还未创建完成无法对this加锁synchronized修饰的方法或代码块在执行过程中如果抛出异常会自动释放锁不会导致锁泄漏。第二章 底层原理synchronized的锁实现机制理解synchronized的底层原理是掌握其核心逻辑的关键。synchronized的底层实现依赖于JVM的指令和对象头结构不同的锁状态偏向锁、轻量级锁、重量级锁对应不同的实现方式其性能也存在巨大差异。本节将从“对象头结构→JVM指令解析→锁状态实现”三个层面深度剖析synchronized的底层原理。2.1 核心前提Java对象头结构synchronized的锁是对象锁而锁的状态信息偏向锁、轻量级锁、重量级锁是存储在Java对象的“对象头”中的。因此要理解synchronized的底层实现首先要掌握Java对象头的结构。Java对象在内存中分为三个部分对象头Header、实例数据Instance Data、对齐填充Padding。其中对象头是synchronized实现锁的核心它存储了对象的锁状态、哈希码、GC分代年龄等信息。2.1.1 对象头的组成以HotSpot JVM为例HotSpot JVM的对象头分为两部分Mark Word标记字段和Klass Pointer类型指针。1. Mark Word标记字段Mark Word是对象头的核心部分占32位32位JVM或64位64位JVM用于存储对象的锁状态、哈希码hashCode、GC分代年龄、偏向锁标识、偏向线程ID等信息。为了节省内存Mark Word的结构会根据对象的锁状态动态变化不同锁状态下的Mark Word结构不同。64位JVM下Mark Word的默认结构无锁状态如下不同锁状态下Mark Word的结构会发生变化核心变化如下无锁状态存储哈希码、GC分代年龄、锁状态标志01、偏向锁标志0偏向锁状态存储偏向线程ID、偏向时间戳、GC分代年龄、锁状态标志01、偏向锁标志1轻量级锁状态存储轻量级锁的指针指向线程栈中的锁记录、锁状态标志00重量级锁状态存储重量级锁的指针指向操作系统的互斥锁、锁状态标志10。2. Klass Pointer类型指针Klass Pointer占32位32位JVM或64位64位JVM用于指向对象对应的Class对象即对象的类型信息JVM通过该指针确定对象的类型。例如new Object()创建的对象其Klass Pointer指向Object.class。注意64位JVM中为了节省内存Klass Pointer可以通过“压缩指针”技术压缩为32位默认开启。3. 对齐填充Padding对齐填充是可选部分用于保证对象的总大小是8字节的整数倍HotSpot JVM要求对象内存大小必须是8字节的整数倍这是为了提高内存访问效率。如果对象头实例数据的大小不是8字节的整数倍就会通过对齐填充补充空白字节。2.1.2 对象头与synchronized的关系synchronized的锁状态本质上是通过修改对象头中Mark Word的“锁状态标志”和“偏向锁标志”来实现的。当线程获取锁时会修改对象头的Mark Word当线程释放锁时会恢复Mark Word的状态。不同的锁状态对应不同的Mark Word结构也对应不同的锁实现机制。核心结论synchronized的锁是“对象锁”锁的状态存储在对象的Mark Word中JVM通过修改Mark Word的内容来实现锁的获取和释放。2.2 JVM指令解析synchronized的编译原理当我们用synchronized修饰方法或代码块时Java编译器会将其编译为对应的JVM指令这些指令负责实现锁的获取和释放。通过分析JVM指令我们可以更直观地理解synchronized的底层执行逻辑。2.2.1 修饰代码块的JVM指令synchronized修饰代码块时编译器会在代码块的开始位置插入“monitorenter”指令在代码块的结束位置包括异常处理位置插入“monitorexit”指令。其中monitorenter对应锁的获取monitorexit对应锁的释放。示例编译后的JVM指令分析使用javap -c SynchronizedDemo5命令查看编译后的JVM指令核心部分指令分析0-4行获取锁对象lock并将其压入操作数栈5行monitorenter指令线程尝试获取锁进入monitor。如果锁未被占用线程获取锁并将monitor的计数器加1如果锁已被占用线程阻塞等待6-11行执行代码块中的逻辑打印字符串18行monitorexit指令线程释放锁将monitor的计数器减1。当计数器为0时锁被释放其他阻塞的线程可以尝试获取锁27行异常情况下的monitorexit指令确保即使代码块抛出异常锁也能被释放避免锁泄漏。核心概念monitor监视器。每个Java对象都对应一个monitormonitor是synchronized底层实现的核心它本质上是一个操作系统的互斥锁mutex用于实现线程间的互斥。当线程执行monitorenter指令时会尝试获取monitor的所有权当执行monitorexit指令时会释放monitor的所有权。2.2.2 修饰方法的JVM指令synchronized修饰实例方法或静态方法时编译器不会插入monitorenter和monitorexit指令而是通过修改方法的“访问标志”access_flags来实现锁的功能。具体来说synchronized修饰实例方法时方法的访问标志会增加“ACC_SYNCHRONIZED”标识synchronized修饰静态方法时方法的访问标志也会增加“ACC_SYNCHRONIZED”标识。当JVM执行带有ACC_SYNCHRONIZED标识的方法时会自动获取锁实例方法锁对象为当前实例this获取锁即获取this对象的monitor静态方法锁对象为当前类的Class对象获取锁即获取Class对象的monitor。方法执行完毕或抛出异常后JVM会自动释放锁无需手动插入monitorexit指令。示例synchronized实例方法的JVM指令可以看到方法的flags中包含“ACC_SYNCHRONIZED”标识这就是synchronized修饰方法的底层实现方式——通过JVM自动识别该标识完成锁的获取和释放。2.3 锁的底层实现从无锁到重量级锁的演进在Java 1.6之前synchronized的锁只有“无锁”和“重量级锁”两种状态重量级锁的实现依赖于操作系统的互斥锁mutex而操作系统的线程切换需要从用户态切换到内核态开销巨大导致synchronized的性能较差被开发者称为“重量级锁”。为了优化synchronized的性能Java 1.6引入了“锁升级”机制增加了“偏向锁”和“轻量级锁”两种状态。锁升级的核心逻辑是根据线程竞争的激烈程度从无锁→偏向锁→轻量级锁→重量级锁逐步升级避免一开始就使用重量级锁从而减少锁的开销提高并发性能。锁升级的顺序是“不可逆”的即一旦升级为重量级锁就无法再降级为轻量级锁或偏向锁。下面我们分别详细讲解每种锁的实现原理、适用场景和性能特点。2.3.1 无锁状态Unlocked无锁状态是对象的初始状态此时对象没有被任何线程锁定Mark Word中存储的是对象的哈希码、GC分代年龄、锁状态标志01、偏向锁标志0。适用场景没有线程竞争共享资源此时不需要加锁程序执行效率最高。核心特点无锁竞争无任何锁开销线程可以自由访问共享资源但此时可能存在线程安全问题因此无锁状态只适用于无并发竞争的场景。2.3.2 偏向锁Biased Lock无竞争场景的优化偏向锁是Java 1.6引入的第一种优化锁其核心设计思想是如果一个线程多次获取同一把锁且期间没有其他线程竞争该锁那么就将该线程标记为“偏向线程”后续该线程获取锁时无需进行复杂的锁竞争直接获取锁从而减少锁的开销。偏向锁的适用场景单线程重复获取同一把锁无并发竞争这是最常见的场景如单线程操作共享资源、方法的多次调用。1. 偏向锁的实现原理偏向锁的实现依赖于对象头Mark Word的修改具体流程如下线程第一次获取锁时检查对象的Mark Word此时锁状态为无锁01偏向锁标志为0线程将自己的线程ID、偏向时间戳写入对象的Mark Word同时将偏向锁标志设为1锁状态标志保持01此时Mark Word表示偏向锁状态后续该线程再次获取锁时只需检查Mark Word中的偏向线程ID是否为当前线程ID如果是直接获取锁无需任何额外操作无需CAS操作无需阻塞如果不是说明有其他线程竞争锁此时偏向锁需要升级为轻量级锁。线程释放偏向锁时不会主动修改Mark Word避免不必要的开销只有当有其他线程竞争锁时才会释放偏向锁将Mark Word恢复为无锁状态或升级为轻量级锁。2. 偏向锁的优势与不足优势开销极小单线程重复获取锁时无需CAS操作、无需阻塞线程几乎没有锁开销性能接近无锁状态适用场景广泛很多场景下共享资源的访问都是单线程的如单线程操作缓存、单线程处理任务偏向锁能大幅提升这类场景的性能。不足存在锁撤销开销当有其他线程竞争锁时需要撤销偏向锁升级为轻量级锁这个过程会产生一定的开销不适合多线程竞争场景如果多个线程频繁竞争同一把锁偏向锁会频繁被撤销、升级反而会降低性能。3. 偏向锁的开启与关闭Java 1.6及以后偏向锁默认开启。我们可以通过JVM参数控制偏向锁的开启与关闭开启偏向锁默认-XX:UseBiasedLocking关闭偏向锁-XX:-UseBiasedLocking。注意偏向锁的开启有一个延迟默认4秒这是因为JVM启动初期会有很多线程竞争锁此时开启偏向锁反而会影响性能。我们可以通过-XX:BiasedLockingStartupDelay0参数取消延迟让偏向锁立即开启。2.3.3 轻量级锁Lightweight Lock低竞争场景的优化当有两个线程竞争同一把锁低竞争场景偏向锁会被撤销升级为轻量级锁。轻量级锁的核心设计思想是通过CAS操作Compare and Swap实现锁的获取和释放避免使用操作系统的互斥锁减少用户态到内核态的切换开销。轻量级锁的适用场景两个线程交替竞争同一把锁低并发竞争此时线程无需阻塞通过CAS操作即可获取锁。1. 轻量级锁的实现原理轻量级锁的实现依赖于线程栈中的“锁记录”Lock Record和对象头Mark Word的修改具体流程如下线程获取锁时检查对象的Mark Word此时偏向锁已被撤销锁状态为无锁01线程在自己的线程栈中创建一个锁记录Lock Record锁记录中存储对象的Mark Word副本称为“Displaced Mark Word”以及锁对象的指针线程通过CAS操作将对象的Mark Word修改为指向自己线程栈中锁记录的指针同时将锁状态标志设为00此时Mark Word表示轻量级锁状态如果CAS操作成功说明线程获取到了轻量级锁继续执行临界区代码如果CAS操作失败说明有其他线程正在竞争锁此时轻量级锁需要升级为重量级锁。线程释放轻量级锁时通过CAS操作将对象的Mark Word恢复为原来的Displaced Mark Word无锁状态如果CAS操作成功说明没有其他线程竞争锁锁释放成功如果CAS操作失败说明有其他线程正在竞争锁此时锁已升级为重量级锁线程会直接释放重量级锁。2. 锁记录Lock Record的作用锁记录是线程栈中的一块内存区域用于存储锁对象的Mark Word副本和锁对象指针。其核心作用是8a.1h4d.com、7h.9xph.com、3z.9xph.com、nm.3md6.com、9j.41rgw.com、n7.41rgw.com、g3.h2r2m.com、1u.g3.h2r2m.com、o2.g3.h2r2m.com、j5.g3.h2r2m.com、g5.g3.h2r2m.com、eg.or4io.com、c4.or4io.com、6l.or4io.com、9n.8tmow.com、z2.tp9z7.com、1l.uck71.com、e4.is9j.cn、m.is9j.cn、lck.is9j.cn、ys.is9j.cn、www.is9j.cn、pds.is9j.cn、f3.ba5c2.cn、h6.ba5c2.cn、0c.oo.azi6.cn、8u.um70.cn、um70.cn、zd.um70.cn、3t.um70.cn、c5.3yfx.cn、d0.kw3y.cn、9c.kw3y.cn、hm.kw3y.cn、2s.6meo.cn、sd.bautir.cn、i5.bixqw.cn、a4.bixqw.cn、za.zjmvm.cn、z2.zjmvm.cn、x1.zjmvm.cn、d4.omzgb.cn、j9.czmdu.cn、a5.czmdu.cn、6o.czmdu.cn、8s.cwu4.cc、z61l.cc、ef.z61l.cc、a7.6dlx.cc、tkf9.cc、7t.tkf9.cc、s0.tkf9.cc、3u.tkf9.cc、8g.tkf9.cc、rt.tkf9.cc、no.tkf9.cc、6q.58sba.cc、ru.4j7sr.cc、9x.fs.lpij.net、jm.fs.lpij.net、afk.su5ba2in09.org、w8.baggq.org、b1.baggq.org、un.baggq.org、9a.bai0v.org、0j.bai0v.org、t6.bai0v.org、u0.bai0v.org、z6.bai0v.org、3t.r5.ba11o.org、g1.r5.ba11o.org、g0.r5.ba11o.org、5c.r5.ba11o.org、j9.r5.ba11o.org、5h.r5.ba11o.org、bc.sb0.org、no.sb0.org、2u.7o.9h1e.org、j9.xvn7.cc、no.9qga.cc、7h.otbrf.cn、rn.2fs.mobi、rp.2fs.mobi、7m.2fs.mobi、ag.2q5.net、kq.2q5.net、jx.2q5.net、4h.ml.baucr.cc、9n.ml.baucr.cc、afk.su5ba2in09.org存储Mark Word副本用于释放锁时恢复对象的Mark Word标识当前线程持有该锁便于JVM跟踪锁的持有状态。3. 轻量级锁的优势与不足优势开销较小通过CAS操作实现锁的获取和释放无需切换到内核态比重量级锁的性能高很多适合低竞争场景两个线程交替竞争锁时无需阻塞线程执行效率高。不足CAS操作存在自旋开销当多个线程竞争锁时CAS操作会失败线程会进行自旋循环尝试CAS自旋会消耗CPU资源不适合高竞争场景当多个线程同时竞争锁时自旋会持续消耗CPU此时升级为重量级锁反而更高效。2.3.4 重量级锁Heavyweight Lock高竞争场景的兜底方案当有多个线程同时竞争同一把锁高竞争场景轻量级锁会升级为重量级锁。重量级锁的核心实现是依赖于操作系统的互斥锁mutex线程获取锁时如果锁已被占用线程会被阻塞进入内核态直到锁被释放后线程才会被唤醒重新尝试获取锁。重量级锁的适用场景多个线程同时竞争同一把锁高并发竞争此时线程阻塞的开销比自旋的开销更小。2b.s6.ba2u.biz、5k.s6.ba2u.biz、7z.bartr.biz、cq.ri.baoip.biz、io.ln.baoip.biz、ie.rm.x5my.biz、h7.c0.x5my.biz、8d.ii.x5my.biz、pz.ii.x5my.biz、rv.d5h9.biz、th.d5h9.biz、as.pyo2.biz、fc.pyo2.biz、g5.pyo2.biz、uf.pyo2.biz、r1.pyo2.biz、xb.pyo2.biz、vb.pyo2.biz、4m.pyo2.biz、py.pyo2.biz、bk.pyo2.biz、1i.pyo2.biz、5f.pyo2.biz、5u.pyo2.biz、h7.pyo2.biz、ng.a2sy.biz、n9.2mn.mobi、qy.2mn.mobi、ki.2mn.mobi、gw.2mn.mobi、xa.2mn.mobi、4o.2mn.mobi、zp.2mn.mobi、zq.3no.mobi、pg.3no.mobi、jp.6pq.mobi、k8.6pq.mobi、b8.6pq.mobi、yq.6pq.mobi、x2.6pq.mobi、hz.6pq.mobi、2k.ba2g.biz、ab.ba2g.biz、w3.ba2g.biz、i2.ab4i.biz、w2.ab4i.biz、5h.ab4i.biz、av.hh33.mobi、ma.hh33.mobi、6t.hh33.mobi、1h.hh33.mobi、lr.hh33.mobi、ae.hh33.mobi、sx.hh33.mobi、k3.tc3.mobi、ml.tc3.mobi、p6.xj.br7.biz、qf.st.1va.biz、ot.st.1va.biz、5r.i2c.mobi、zb.i2c.mobi、l8.i2c.mobi、3h.ui.aby7.biz、9g.ba8q.biz、3o.ba8q.biz、2w.bag0.biz、7w.ah5.biz、t4.ah5.biz、5i.8ks.biz、3r.8ks.biz、9x.f4.0ip.biz、h8.4t.0wra.biz、x2.bal6.biz、1. 重量级锁的实现原理重量级锁的实现依赖于对象的monitor监视器而monitor的底层是操作系统的互斥锁mutex具体流程如下线程获取锁时检查对象的Mark Word此时轻量级锁已升级为重量级锁锁状态标志为10线程尝试获取对象的monitor即操作系统的互斥锁如果monitor未被占用线程获取monitor的所有权将monitor的计数器加1继续执行临界区代码如果monitor已被占用线程会被阻塞进入内核态放入monitor的等待队列中直到monitor被释放。线程释放锁时释放monitor的所有权将monitor的计数器减1。当计数器为0时monitor被释放等待队列中的一个线程会被唤醒重新尝试获取monitor。2. 重量级锁的核心特点3.1 可重入性同一线程可多次获取同一把锁synchronized是“可重入锁”Reentrant Lock即同一个线程可以多次获取同一把锁不会导致死锁。可重入性的核心目的是避免线程在获取自己已经持有的锁时被阻塞提高程序的灵活性和可读性。3.1.1 可重入性的示例演示示例1同一线程多次调用synchronized实例方法可重入核心原则锁升级是“按需升级”根据线程竞争的激烈程度从低开销的锁逐步升级为高开销的锁最大化提升并发性能。第三章 核心特性synchronized的可重入性与非公平性除了锁升级机制synchronized还有两个核心特性可重入性和非公平性。这两个特性直接影响synchronized的使用场景和性能也是面试中的高频考点。本节将详细讲解这两个特性的原理、实现方式和实际影响。开销大线程获取锁和释放锁时需要从用户态切换到内核态操作系统级别的线程切换这个过程开销巨大线程阻塞当锁被占用时其他线程会被阻塞不会消耗CPU资源相比轻量级锁的自旋适合高竞争场景稳定性高无论竞争多么激烈重量级锁都能保证线程安全是锁升级的兜底方案。2.3.5 锁升级的完整流程总结结合前面的讲解synchronized的锁升级完整流程如下初始状态对象处于无锁状态Mark Word存储哈希码、GC分代年龄锁状态标志01偏向锁标志0单线程获取锁升级为偏向锁Mark Word写入偏向线程ID偏向锁标志设为1锁状态标志01有第二个线程竞争锁撤销偏向锁升级为轻量级锁线程通过CAS操作修改Mark Word锁状态标志设为00有多个线程同时竞争锁轻量级锁升级为重量级锁依赖操作系统互斥锁锁状态标志设为10web.421o14.com、421o2.com、we.424q26.com、bbs.424q26.com、am.424q26.com、tti.569au.com、dp.oy514e3.cc、u6.jhgksfku.org、6n.jhgksfku.org、9q.jhgksfku.org、163.felora.info、v.felora.info、h.felora.info、we.4ekyf.cc、n9.oo5.mobi、dh.byf2h.mobi、5t.byf2h.mobi、k2.9qr.biz、jk.g5h.biz、1z.3ef.biz、cw.3ef.biz、0g.t9s.mobi、f0.baf2p.biz、2b.baf2p.biz、cd.baf2p.biz、3f.baf2p.biz、1u.baf2p.biz、j2.z2y.biz、xk.ba4j5.biz、8u.ba4j5.biz、4h.ba4j5.biz、9d.ba4j5.biz、yn.ba4j5.biz、b8.ba4j5.biz、lk.ba4j5.biz、qt.pp6.biz、mw.pp6.biz、5g.pp6.biz、s2.pp6.biz、gp.pp6.biz、p8.pp6.biz、fn.pp6.biz、5z.bagt5.biz、4m.bamnn.biz、3m.0r.bauuo.biz、ca.ku.rby0.biz、5t.sj.rby0.biz、z4.zn.ba0g.biz、rd.9b.ba0g.biz、mf.9b.ba0g.biz、锁释放偏向锁不主动释放只有竞争时才撤销轻量级锁通过CAS恢复Mark Word重量级锁释放monitor唤醒等待队列中的线程。分析outer方法和inner方法都是synchronized实例方法锁对象都是this。线程调用outer方法时获取锁然后在outer方法中调用inner方法此时线程已经持有this锁能够直接获取锁可重入不会被阻塞。示例2同一线程多次获取synchronized代码块锁可重入