Spring @Service单例Bean并发调用是否会引发线程干扰问题
@Slf4j @Service public class BookingServiceImpl implements BookingService { private final AirTicketService airTicketService; @Autowired public BookingServiceImpl(AirTicketService airTicketService) { this.airTicketService = airTicketService; } @Transactional @Override public boolean bookTicket(Customer customer) { return this.airTicketService.reserve(customer); } }
线程干扰判定
该场景不会发生线程干扰,核心依据如下:
- 线程干扰的触发前提是多个线程并发读写同一个共享可变资源,当前场景不满足该前提。
BookingServiceImpl是单例Bean,内部仅持有final修饰的AirTicketService引用,构造注入完成后引用不会变更,不存在可变的共享成员变量,本身无竞态条件。- 10个并发调用传入的都是全新创建的
Customer实例,每个实例仅归属于当前调用线程,没有被多线程共享。方法参数customer是线程栈上的局部引用,属于线程私有资源,其他线程无法直接访问。
Customer数据污染判定
两个单例Bean默认不会导致传入的Customer对象数据被污染,说明如下:
- 单例Bean的线程安全风险仅来自自身持有的可变共享成员变量,
BookingService和AirTicketService都没有定义Customer类型的共享成员,不会把传入的Customer实例缓存到Bean的全局共享域供其他线程访问。 - 方法执行过程中对
customer的读写操作,都只作用于当前线程传入的独有实例,不会跨线程篡改其他请求的Customer数据。 - 唯一的例外情况:如果
AirTicketService.reserve()方法本身做了线程不安全的实现,比如把传入的customer存入静态集合、单例持有的共享集合等全局可访问的域中,供其他线程读写,才可能出现数据污染。这类问题属于业务代码的实现缺陷,和单例Bean本身的特性无关。
内容的提问来源于stack exchange,提问作者user13763706
相关产品推荐
相关产品推荐

