springboot synchronized 本地锁入门与实战

Spring Boot3 Synchronized 项目地址

https://gitee.com/supervol/loong-springboot-study

(记得给个start,感谢)

Synchronized 概述

在 Spring Boot 3 应用中,synchronized作为 Java 原生的线程同步机制,是实现本地锁(仅在当前 JVM 进程内生效)的基础工具,用于解决单实例应用中的并发安全问题。

Synchronized 核心

synchronized是Java 的关键字,其核心作用是保证同一时刻只有一个线程执行特定代码块 ,从而避免多线程并发访问共享资源时出现的数据不一致(如脏读、重复修改等)问题。在 Spring Boot 3 中,它的本质是本地锁:仅对当前 JVM 进程内的线程有效,无法跨进程(如分布式部署的多实例应用)同步,这是与分布式锁(如 Redis 锁、ZooKeeper 锁)的核心区别。

Synchronized 使用

在 Spring Boot 3 中,synchronized的使用方式与标准 Java 一致,主要有以下 3 种:

1. 修饰实例方法

锁对象为当前对象实例this),即多个线程调用同一对象的该方法时会被同步。

复制代码
@Service
public class StockService {
    private int stock = 100; // 共享资源
    
    // 修饰实例方法:锁为当前StockService实例(单例Bean时全局有效)
    public synchronized void deductStock() {
        if (stock > 0) {
            stock--;
            System.out.println("扣减成功,剩余库存:" + stock);
        } else {
            System.out.println("库存不足");
        }
    }
}

注:Spring Boot 默认 Bean 为单例,因此该锁对所有调用该 Bean 的线程生效。

2. 修饰静态方法

锁对象为当前类的 Class 对象 (如StockService.class),作用范围是整个类,即使多个实例也会被同步。

复制代码
@Service
public class CounterService {
    private static int count = 0; // 静态共享资源
    
    // 修饰静态方法:锁为CounterService.class
    public static synchronized void increment() {
        count++;
        System.out.println("计数:" + count);
    }
}

3. 修饰代码块

显式指定锁对象(可自定义),灵活性更高,能缩小同步范围以提升性能。

复制代码
@Service
public class OrderService {
    private final Object lock = new Object(); // 自定义锁对象
    private int orderId = 0;
    
    public void createOrder() {
        // 仅同步关键代码块,锁为lock对象
        synchronized (lock) {
            orderId++;
            System.out.println("生成订单ID:" + orderId);
        }
        // 非关键代码(如日志、参数校验)无需同步,提升效率
        System.out.println("订单创建完成");
    }
}

Synchronized示例

请参考项目地址中 springboot-lock/springboot-local-lock 模块代码。

Synchronized 原理

synchronized的底层依赖 JVM 的对象监视器(Monitor) 机制,通过修改对象头中的Mark Word(存储锁状态)实现锁的获取与释放:

  • 当线程进入synchronized代码块时,会尝试获取锁对象的 Monitor,若成功则独占锁;
  • 其他线程会被阻塞并进入等待队列,直到持有锁的线程释放 Monitor(退出代码块)。

Java 6 及以上对synchronized进行了优化,引入了锁升级机制(偏向锁 → 轻量级锁 → 重量级锁),大幅提升了低并发场景下的性能:

  • 偏向锁:无竞争时,仅记录线程 ID,几乎无开销;
  • 轻量级锁:轻度竞争时,通过 CAS(比较并交换)尝试获取锁,避免线程阻塞;
  • 重量级锁:重度竞争时,依赖操作系统互斥量实现,会导致线程阻塞(开销较大)。

Synchronized 场景

synchronized适用于单实例 Spring Boot 应用,解决以下并发问题:

  1. 共享资源修改:如库存扣减、计数器累加、订单 ID 生成等;
  2. 临界区代码保护:如防止多线程同时执行初始化操作(如加载配置);
  3. 避免重复处理:如防止同一请求被多个线程重复处理(需配合幂等设计)。

Synchronized 注意

  1. 仅支持本地锁 :多实例部署(分布式系统)时,synchronized无法跨 JVM 同步,需使用分布式锁(如 Redisson、Curator);
  2. 锁粒度问题:同步范围过大(如修饰整个方法)可能导致性能下降,建议用代码块缩小范围;
  3. Bean 作用域影响 :若 Spring Bean 为原型(prototype),实例方法的synchronized锁仅对当前实例有效,可能无法实现全局同步(需改用静态方法或类锁);
  4. 不可中断性 :持有锁的线程若阻塞(如 IO 操作),其他线程会一直等待,可考虑ReentrantLock(支持中断)作为替代。

总结

synchronized是 Spring Boot 3 单实例应用中实现线程安全的简单有效工具,通过原生 Java 机制保证本地并发安全,适合低至中并发场景。但在分布式环境或需要更灵活锁控制(如超时、中断)的场景中,需结合其他同步方案(如分布式锁、ReentrantLock)使用。

相关推荐
码路飞18 分钟前
GPT-5.3 Instant 终于学会好好说话了,顺手对比了下同天发布的 Gemini 3.1 Flash-Lite
java·javascript
洋洋技术笔记23 分钟前
Spring Boot Web MVC配置详解
spring boot·后端
SimonKing1 小时前
OpenCode AI编程助手如何添加Skills,优化项目!
java·后端·程序员
Seven972 小时前
剑指offer-80、⼆叉树中和为某⼀值的路径(二)
java
怒放吧德德14 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆15 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌18 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
初次攀爬者19 小时前
Kafka 基础介绍
spring boot·kafka·消息队列
华仔啊19 小时前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang19 小时前
用六边形架构与整洁架构对比是伪命题?
java·架构