当前位置: 首页 > news >正文

Java多线程编程实战:synchronized与Lock锁对比


一、锁机制全景图:从内核态到用户态

1. Java锁分类与演进史

锁机制
悲观锁
乐观锁
synchronized
ReentrantLock
CAS
版本号机制

2. 锁升级全流程(synchronized底层原理)

无锁 → 偏向锁(单线程) → 轻量级锁(CAS自旋) → 重量级锁(OS互斥量)  

锁膨胀条件

  • 偏向锁:-XX:BiasedLockingStartupDelay=0(默认延迟4秒)
  • 重量级锁:自旋超过阈值(-XX:PreBlockSpin=10)或竞争激烈

二、synchronized与ReentrantLock核心差异

对比维度synchronizedReentrantLock
实现层级JVM内置(C++实现)Java API(AQS实现)
锁释放自动(代码块结束)必须手动unlock()
中断响应不支持支持lockInterruptibly()
公平性非公平(默认)可选公平/非公平(构造参数)
条件变量单个monitor条件可创建多个Condition
性能JDK6后优化接近Lock高竞争下更优

三、底层实现深度剖析

1. synchronized监视器锁结构

// HotSpot对象头Mark Word结构(64位)  
| 锁状态  | 25bit          | 31bit                   | 1bit | 4bit |  
|---------|----------------|-------------------------|------|------|  
| 无锁    | 未使用         | 对象hashCode            | 0    | 001  |  
| 偏向锁  | 线程ID+epoch   |                         | 1    | 001  |  
| 轻量锁  | 指向栈中锁记录 |                         |      | 000  |  
| 重量锁  | 指向互斥量指针 |                         |      | 010  |  

2. AQS(AbstractQueuedSynchronizer)核心逻辑

// ReentrantLock获取锁流程  
final void lock() {  
    if (!tryAcquire(1) &&  
        acquireQueued(addWaiter(Node.EXCLUSIVE), 1))  
        selfInterrupt();  
}  

// CLH队列节点结构  
static final class Node {  
    volatile int waitStatus;  
    volatile Node prev;  
    volatile Node next;  
    volatile Thread thread;  
}  

四、性能压测与选型策略(基于JMH)

1. 不同竞争强度下的吞吐量对比

线程数=4,竞争低:  
synchronized: 1,234,567 ops/ms  
ReentrantLock: 1,345,678 ops/ms  

线程数=32,竞争高:  
synchronized: 456,789 ops/ms  
ReentrantLock: 789,012 ops/ms  

2. 选型决策树

需要高级功能?
ReentrantLock
竞争激烈?
ReentrantLock+公平策略
synchronized

五、高并发实战案例

1. 分布式库存扣减(非公平锁优化)

public class InventoryService {  
    private final ReentrantLock lock = new ReentrantLock();  
    private Map<String, Integer> stock = new HashMap<>();  

    public boolean deduct(String itemId, int quantity) {  
        lock.lock();  
        try {  
            int remain = stock.getOrDefault(itemId, 0);  
            if (remain >= quantity) {  
                stock.put(itemId, remain - quantity);  
                return true;  
            }  
            return false;  
        } finally {  
            lock.unlock();  
        }  
    }  
}  

2. 死锁检测与解决(tryLock实践)

public void transfer(Account from, Account to, int amount) {  
    while (true) {  
        if (from.lock.tryLock()) {  
            try {  
                if (to.lock.tryLock()) {  
                    try {  
                        // 转账逻辑  
                        return;  
                    } finally {  
                        to.lock.unlock();  
                    }  
                }  
            } finally {  
                from.lock.unlock();  
            }  
        }  
        Thread.sleep(randomDelay()); // 避免活锁  
    }  
}  

六、锁优化十大黄金法则

  1. 减少锁粒度:拆大锁为小锁(如ConcurrentHashMap分段锁)
  2. 缩短持锁时间:锁内只保留必要操作
  3. 锁分离策略:读写分离(ReentrantReadWriteLock)
  4. 避免嵌套锁:按固定顺序获取锁
  5. 锁消除:-XX:+EliminateLocks(JIT优化)
  6. 锁粗化:合并连续小锁(JIT自动优化)
  7. 偏向锁优化:-XX:+UseBiasedLocking
  8. 自旋锁调优:-XX:PreBlockSpin=20
  9. 适应性自旋:-XX:+UseSpinning
  10. 虚拟线程兼容:Java 21虚拟线程避免锁阻塞

七、Java 21虚拟线程与锁机制

1. 虚拟线程对锁的影响

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {  
    executor.submit(() -> {  
        synchronized(lock) {  // 兼容传统锁  
            // 虚拟线程挂起不会阻塞内核线程  
        }  
    });  
}  

2. 最佳实践:

  • 避免在虚拟线程中使用synchronized长时间阻塞
  • 优先使用ReentrantLock+await(支持线程切换)

八、常见陷阱与高频面试题

1. 陷阱案例:锁对象变更导致失效

private Object lock = new Object();  

public void updateLock() {  
    synchronized(lock) {  
        lock = new Object();  // 后续线程使用不同锁!  
    }  
}  

2. 面试题:为什么synchronized是非公平锁?

答案

  • 减少线程切换开销(唤醒等待线程需要成本)
  • 提高吞吐量(允许新请求插队)

相关文章:

  • 【Mastering Vim 2_11】第八章:玩转 Vimscript(下)—— 从零开始打造一个 Vim9 插件(含完整发布流程)
  • Docker介绍和安装
  • 「MySQL 数据库优化」降低存储与查询成本的最佳实践
  • 【计算机组成原理】第三章 存储系统
  • 第八届蓝桥杯单片机省赛
  • 【08】单片机变量命名规范指南
  • AI编程工具-(七)
  • 【鸿蒙开发】入门篇:node与express
  • 优化 NFS 挂载参数以提升可靠性与容错性
  • Spring Boot 日志
  • LabVIEW基于双通道FFT共轭相乘的噪声抑制
  • 关于统计建模大赛的选题
  • 【鸿蒙开发】Hi3861学习笔记- 软件定时器示例
  • 【Linux】进程间通信
  • 批量创建BOM的RFC接口
  • 常见的设计模式和应用场景(一)
  • 文本转语音-音画适时推送rtsp并播放
  • 静态路由实验
  • Spring Boot/Spring Cloud 整合 ELK(Elasticsearch、Logstash、Kibana)详细避坑指南
  • 【CSS3】元婴篇
  • 科技日报刊文批院士专家“赶场式”跑会:助长浮躁之气功利之心
  • IPO周报|节后首批3只新股本周申购,色谱设备龙头来了
  • 夹缝中的责编看行业:长视频之殇,漫长周期
  • 100%关税!特朗普要让美国电影100%美国制造
  • 最会说亚军感言的鲁德,站上了马德里公开赛的冠军领奖台
  • 贵州黔西市载人游船倾覆事故已致3人遇难,14人正在搜救中