惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 时空穿越者

java并发:深入解析 ThreadPoolExecutor.addWorker() 流水线技术解析:处理器重排序的硬件基础 java并发:管道流(Piped Streams)的应用场景 java并发:再次认识一下Java中的锁 —— 类级别的锁是否存在? LangGraph:add_conditional_edges详解 Spring异步机制:@Async Spring BeanDefinition Spring Resource Spring之ApplicationContext Spring之BeanFactory:解析getBean()方法 Spring之IoC容器 Spring的整体架构 Spring Data JPA:解析CriteriaQuery Spring Data JPA:解析CriteriaBuilder Spring Data JPA:解析JpaSpecificationExecutor & Specification Spring Data JPA:解析SimpleJpaRepository java并发:线程池之Executors(ScheduledExecutorService篇) - 时空穿越者 java并发:线程池之饱和策略 java并发:线程池之ThreadPoolExecutor
java并发:synchronized 揭秘
时空穿越者 · 2026-02-09 · via 博客园 - 时空穿越者

synchronized 的内存语义可以解决共享变量内存可见性问题,此外synchronized 经常被用来实现原子性操作(例: signal++ 不是⼀个原⼦操作,需要使⽤ synchronized 给它“上锁”)。

典型应用场景

场景:共享资源修改

// 银行账户扣款
public class Account {
    private double balance;
    
    public synchronized void deduct(double amount) {
        if (balance >= amount) {
            balance -= amount;
        }
    }
}
public class Counter {
    private int count = 0;
    
    // 需要显式同步
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}

必要性:必须通过锁保证共享状态的一致性

重要特性

可重入锁(Reentrant Lock)

public class ReentrantDemo {
    public synchronized void methodA() {
        System.out.println("Enter methodA");
        methodB(); // 嵌套调用同步方法
    }

    public synchronized void methodB() {
        System.out.println("Enter methodB");
    }
}

执行流程:

graph TB
    Thread[线程] -->|获取对象锁| methodA
    methodA -->|无需重新申请锁| methodB
    methodB -->|执行完毕| Release[释放锁]

关键点:同一个线程在持有锁的情况下,可以多次进入同一把锁保护的代码区域【可重入性仅适用于同一把锁(相同对象或 Class 对象)

可重入性边界案例

public class StaticLock {
    public synchronized static void staticMethod() {
        instanceMethod(); // 非重入!锁对象不同
    }
    
    public synchronized void instanceMethod() { ... }
}

锁对象差异:

staticMethod 锁定 StaticLock.class
instanceMethod 锁定 this 实例

现代替代方案:ReentrantLock

private final ReentrantLock lock = new ReentrantLock();

public void execute() {
    lock.lock(); // 显式获取锁
    try {
        nestedCall();
    } finally {
        lock.unlock();
    }
}

private void nestedCall() {
    lock.lock(); // 可重入获取
    try {
        // ...
    } finally {
        lock.unlock();
    }
}

优势:

支持公平锁
提供 tryLock() 超时机制
可中断的锁获取

补充:可重入性设计的必要性

示例1:

public class BankAccount {
    public synchronized void transfer(BankAccount target, int amount) {
        this.withdraw(amount); // 重入
        target.deposit(amount);
    }
    
    public synchronized void withdraw(int amount) { ... }
    public synchronized void deposit(int amount) { ... }
}

解读:

业务逻辑:转账操作需原子性完成扣款和存款
技术支撑:可重入锁保证同步方法嵌套调用不阻塞

示例2:

class Base {
    public synchronized void baseMethod() { ... }
}

class Sub extends Base {
    @Override
    public synchronized void baseMethod() {
        super.baseMethod(); // 重入父类同步方法
        // 子类扩展逻辑
    }
}

继承兼容:子类重写方法可通过 super 调用父类同步逻辑

JVM 执行机制

每个 Java 对象都与一个 monitor 关联(通过 ObjectMonitor 实现):

// HotSpot JVM 源码 (objectMonitor.hpp)
class ObjectMonitor {
    volatile intptr_t _count;    // 锁重入计数器
    volatile intptr_t _owner;    // 持有锁的线程指针
    volatile intptr_t _recursions; // 重入次数
};

重入过程:

首次加锁:_owner = current_thread, _count = 1
重入时:_count++, _recursions++
解锁时:_count--,直到 _count = 0 时真正释放锁

对象级锁(Instance-Level Lock) VS 类级锁(Class-Level Lock)

对象级锁

核心定义:当需要同步非静态方法或非静态代码块时,对象级锁确保在同一个类的特定实例上,只有一个线程能执行该同步代码

关键特性:

锁绑定到具体对象实例(this)
不同实例的锁相互独立
实例销毁时锁自动释放

补充:

下⾯这两个⽅法是等价的

image

类级锁

核心定义:类级锁用于同步静态方法或静态代码块,确保在任何时候只有一个线程能访问类的静态数据

public class GlobalConfig {
    private static int configVersion = 0;
    
    // 类级锁实现方式1:静态同步方法
    public static synchronized void updateConfig() {
        configVersion++;
    }
    
    // 实现方式2:同步类对象
    public static void safeUpdate() {
        synchronized (GlobalConfig.class) { // 锁定Class对象
            configVersion++;
        }
    }
}

关键特性:

锁绑定到类的Class对象(ClassName.class)
所有实例共享同一把锁
JVM卸载类时锁释放

补充:

下⾯这两个⽅法是等价的

image

对比分析

image

开发者负担

(1)需精准识别临界区
(2)要处理锁嵌套和死锁风险
(3)必须考虑锁粒度(方法锁 vs 代码块锁)

最佳实践:优先使用同步块而非同步方法,明确锁范围

并发瓶颈

graph LR
    Thread1-->|等待锁| CriticalSection[临界区]
    Thread2-->|阻塞| CriticalSection
    Thread3-->|阻塞| CriticalSection

锁竞争代价:

(1)线程切换开销:Linux 下约 1-10μs/次
(2)吞吐量衰减:高并发时性能曲线呈断崖式下降

实现机制

// HotSpot JVM 锁实现伪代码
void ObjectMonitor::enter() {
    if (TryLock()) return;     // 快速路径
    if (TrySpin()) return;     // 自旋优化
    EnqueueToWaitList();       // 加入等待队列
    Park();                    // 挂起线程(内核切换)
}

性能陷阱:

锁膨胀:无竞争→偏向锁→轻量级锁→重量级锁
等待队列管理:O(n) 复杂度的唤醒操作