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

Spring Bean 作用域设置为prototype在并发场景下是否是线程安全的

在并发场景下,将 Spring Bean 作用域设置为 prototype 通常能在一定程度上保证线程安全,但这并不意味着绝对的线程安全

1. prototype 作用域的特点

在 Spring 中,Bean 的作用域定义了 Bean 的生命周期和可见性。prototype 作用域表示每次从 Spring 容器中获取 Bean 时,容器都会创建一个新的 Bean 实例。这与 singleton 作用域不同,singleton 作用域的 Bean 在整个 Spring 容器中只有一个实例。

2. 为何通常能在一定程度上保证线程安全

由于每次请求都会创建一个新的 Bean 实例,不同线程获取到的是不同的 Bean 对象。因此,各个线程对 Bean 的操作不会相互影响,避免了多个线程同时访问和修改同一个 Bean 实例的状态,从而减少了线程安全问题的发生。

以下是一个简单的示例代码:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;// 配置类
@Configuration
class AppConfig {@Bean@Scope("prototype")public MyBean myBean() {return new MyBean();}
}// 自定义 Bean 类
class MyBean {private int count = 0;public void increment() {count++;System.out.println(Thread.currentThread().getName() + " - Count: " + count);}
}// 主类
public class PrototypeScopeExample {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 创建两个线程Thread thread1 = new Thread(() -> {MyBean bean1 = context.getBean(MyBean.class);for (int i = 0; i < 3; i++) {bean1.increment();}});Thread thread2 = new Thread(() -> {MyBean bean2 = context.getBean(MyBean.class);for (int i = 0; i < 3; i++) {bean2.increment();}});// 启动线程thread1.start();thread2.start();try {// 等待线程执行完毕thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 关闭 Spring 容器context.close();}
}

在上述代码中,MyBean 的作用域为 prototypethread1thread2 分别获取到不同的 MyBean 实例,它们对各自实例的 count 变量进行操作,不会相互干扰。

3. 为何不是绝对的线程安全

虽然 prototype 作用域的 Bean 本身不会被多个线程共享,但如果 Bean 内部引用了其他 singleton 作用域的 Bean,并且这些 singleton Bean 不是线程安全的,那么仍然可能会出现线程安全问题。

例如:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;// 配置类
@Configuration
class AppConfig2 {@Bean@Scope("prototype")public MyPrototypeBean myPrototypeBean() {return new MyPrototypeBean();}@Beanpublic MySingletonBean mySingletonBean() {return new MySingletonBean();}
}// 单例 Bean 类
class MySingletonBean {private int sharedCount = 0;public void incrementSharedCount() {sharedCount++;System.out.println(Thread.currentThread().getName() + " - Shared Count: " + sharedCount);}
}// 原型 Bean 类
class MyPrototypeBean {private final MySingletonBean singletonBean;public MyPrototypeBean() {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class);this.singletonBean = context.getBean(MySingletonBean.class);}public void doSomething() {singletonBean.incrementSharedCount();}
}// 主类
public class PrototypeWithSingletonExample {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig2.class);// 创建两个线程Thread thread1 = new Thread(() -> {MyPrototypeBean bean1 = context.getBean(MyPrototypeBean.class);for (int i = 0; i < 3; i++) {bean1.doSomething();}});Thread thread2 = new Thread(() -> {MyPrototypeBean bean2 = context.getBean(MyPrototypeBean.class);for (int i = 0; i < 3; i++) {bean2.doSomething();}});// 启动线程thread1.start();thread2.start();try {// 等待线程执行完毕thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 关闭 Spring 容器context.close();}
}

在这个示例中,MyPrototypeBeanprototype 作用域的 Bean,但它内部引用了 MySingletonBean 这个 singleton 作用域的 Bean。多个 MyPrototypeBean 实例可能会同时访问和修改 MySingletonBeansharedCount 变量,从而导致线程安全问题。

综上所述,将 Spring Bean 作用域设置为 prototype 可以在一定程度上避免线程安全问题,但不能完全保证线程安全,需要根据 Bean 的具体实现和依赖关系进行综合考虑。

相关文章:

Spring Bean 作用域设置为prototype在并发场景下是否是线程安全的

在并发场景下&#xff0c;将 Spring Bean 作用域设置为 prototype 通常能在一定程度上保证线程安全&#xff0c;但这并不意味着绝对的线程安全 1. prototype 作用域的特点 在 Spring 中&#xff0c;Bean 的作用域定义了 Bean 的生命周期和可见性。prototype 作用域表示每次从…...

金融项目实战

测试流程 测试流程 功能测试流程 功能测试流程 需求评审制定测试计划编写测试用例和评审用例执行缺陷管理测试报告 接口测试流程 接口测试流程 需求评审制定测试计划分析api文档编写测试用例搭建测试环境编写脚本执行脚本缺陷管理测试报告 测试步骤 测试步骤 需求评审 需求评…...

mybatis热点面试题第五弹

1. MyBatis与Hibernate的区别 答案&#xff1a; MyBatis&#xff1a; 不完全是一个ORM框架&#xff0c;需要手动编写SQL语句&#xff0c;灵活性高&#xff0c;适合对数据库操作有高性能要求的场景。缺点是无法做到数据库无关性&#xff0c;如果需要支持多种数据库&#xff0c…...

c++头文件和命名空间

在 C 中&#xff0c;头文件和命名空间是两个重要的概念&#xff0c;它们分别用于代码组织和作用域管理。 一、头文件&#xff08;Header Files&#xff09; 1. 作用 声明接口&#xff1a;存放函数、类、变量的声明&#xff08;而非定义&#xff09;。代码复用&#xff1a;通…...

命令行参数和环境变量 ─── linux第13课

目录 命令行参数 命令行参数列表: 如何实现命令行参数传递到此进程 环境变量 基本概念 常见环境变量 查看环境变量方法 ​编辑 环境变量如何写入 总结: 测试PATH 命令行参数 同一个程序,可以根据命令行参数的不同,表现不同功能 比如:指令中的选项的实现. ls -al…...

基于 openEuler 22.09 的 OpenStack Yoga 部署

openEuler 虚拟化环境部署 使用 VMWare Workstation 创建三台 2 CPU、8G内存、100 GB硬盘 的虚拟机 主机 IP 作用 Controller 192.168.184.110 控制节点 Compute 192.168.184.111 计算节点 Storage 192.168.184.112 存储节 一 基础配置 1.1 配置 yum 源 由于 op…...

【Linux实践系列】:用c语言实现一个shell外壳程序

&#x1f525;本文专栏&#xff1a;Linux Linux实践项目 &#x1f338;博主主页&#xff1a;努力努力再努力wz 那么今天我们就要进入Linux的实践环节&#xff0c;那么我们之前学习了进程控制相关的几个知识点&#xff0c;比如进程的终止以及进程的等待和进程的替换&#xff0c;…...

通俗易懂的分类算法之K近邻详解

通俗易懂的分类算法之K近邻详解 用最通俗的语言和例子&#xff0c;来彻底理解 K近邻&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09; 这个分类算法。不用担心复杂的数学公式&#xff0c;我会用生活中的例子来解释&#xff0c;保证你一听就懂&#xff01; 1.…...

NO.19十六届蓝桥杯模拟赛第三期上

1 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问&#xff0c; 2024 的最大的质因数是多少&#xff1f; 答&#xff1a;23 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false)…...

基于 Rust 与 GBT32960 规范的编解码层

根据架构设计&#xff0c;实现编解码层的代码设计 Cargo.toml 加入二进制序列化支持 # 序列化支持 ... bincode "1.3" # 添加二进制序列化支持 bytes-utils "0.1" # 添加字节处理工具 开始编码 错误处理&#xff08;error.rs&#x…...

conda安装及超详细避坑实战

1. Anaconda介绍。 Anaconda是一站式数据科学与机器学习平台&#xff0c;专为开发者、数据分析师设计,并带有python中超过180个科学包及其依赖项。通过 Anaconda&#xff0c;您可以轻松管理数据环境、安装依赖包&#xff0c;快速启动数据分析、机器学习项目。 Anaconda集成了…...

LM studio 加载ollama的模型

1.LM 下载&#xff1a; https://lmstudio.ai/ 2.ollama下载&#xff1a; https://ollama.com/download 3.打开ollama&#xff0c;下载deepseek-r1。 本机设备资源有限&#xff0c;选择7B的&#xff0c;执行ollama run deepseek-r1:7b 4.windows chocolatey下载&#xff1a; P…...

【图论】判断图中有环的两种方法及实现

判断图中有环的两种方法及实现 在图论中&#xff0c;检测有向图是否存在环是常见问题。本文将介绍两种主流方法&#xff1a;DFS三色标记法和拓扑排序&#xff08;Kahn算法&#xff09;&#xff0c;并提供对应的C代码实现。 方法一&#xff1a;DFS三色标记法 核心思想 通过深…...

深入探索像ChatGPT这样的大语言模型-02-POST training supervised finetuning

参考 【必看珍藏】2月6日&#xff0c;安德烈卡帕西最新AI普及课&#xff1a;深入探索像ChatGPT这样的大语言模型&#xff5c;Andrej Karpathy fineweb知乎翻译介绍 fineweb-v1原始连接 fineweb中文翻译版本 Chinese Fineweb Edu数据集 查看网络的内部结果&#xff0c;可以参…...

Kaldi环境配置与Aishell训练

一、项目来源 代码来源&#xff1a;kaldi-asr/kaldi: kaldi-asr/kaldi is the official location of the Kaldi project. (github.com) 官网文档&#xff1a;Kaldi: The build process (how Kaldi is compiled) (kaldi-asr.org) 踩着我的同门李思成-CSDN博客填上的坑kaldi环境…...

数据集/API 笔记:新加坡PSI(空气污染指数)API

data.gov.sg 数据范围&#xff1a;2016年2月 - 2025年3月 1 获取API方式 curl --request GET \--url https://api-open.data.gov.sg/v2/real-time/api/psi 2 返回数据 API 的数据结构可以分为 3 大部分&#xff1a; 区域元数据&#xff08;regionMetadata&#xff09; →…...

【GPU使用】如何在物理机和Docker中指定GPU进行推理和训练

我的机器上有4张H100卡&#xff0c;我现在只想用某一张卡跑程序&#xff0c;该如何设置。 代码里面设置 import os # 记住要写在impot torch前 os.environ[CUDA_VISIBLE_DEVICES] "0, 1"命令行设置 export CUDA_VISIBLE_DEVICES0,2 # Linux 环境 python test.py …...

【Java项目】基于SpringBoot的CSGO赛事管理系统

【Java项目】基于SpringBoot的CSGO赛事管理系统 技术简介&#xff1a;采用SpringBoot框架、Java语言、MySQL数据库等技术实现。 系统简介&#xff1a;CSGO赛事管理系统是一个基于B/S架构的管理系统&#xff0c;主要功能包括前台和后台管理模块。前台系统功能模块分为&#xf…...

MIPI接口:(4)MIPI CSI-2协议详解(上)

1. 什么是CSI&#xff1f; CSI&#xff08;Camera Serial Interface&#xff09;是MIPI联盟早期制定的摄像头接口标准&#xff0c;主要用于连接摄像头和处理器。 CSI-2是CSI的第二代版本&#xff0c;在原有基础上进行了全面优化&#xff1a; &#xff08;1&#xff09;分层架…...

防火墙旁挂组网双机热备负载均衡

一&#xff0c;二层交换网络&#xff1a; 使用MSTPVRRP组网形式 VLAN 2--->SW3为主,SW4 作为备份 VLAN 3--->SW4为主,SW3 作为备份 MSTP 设计 --->SW3 、 4 、 5 运行 实例 1 &#xff1a; VLAN 2 实例 2 &#xff1a; VLAN 3 SW3 是实例 1 的主根&#xff0c;实…...

JMeter 实战项目脚本录制最佳实践(含 BadBoy 录制方式)

JMeter 实战项目脚本录制最佳实践&#xff08;含 BadBoy 录制方式&#xff09; 一、项目背景 在软件测试过程中&#xff0c;使用 JMeter 进行性能测试和功能测试是常见的操作。本实战项目将详细介绍如何使用 JMeter 自带工具以及 BadBoy 进行脚本录制&#xff0c;并完善脚本以…...

硅基流动nodejs流式输出

使用JavaScript的api直接在前端问答速度虽然快但是有token直接暴露的风险。 现在使用nodejs也可以快速进行流式输出并且可以隐藏用户敏感信息。 const express require(express); const axios require(axios); const app express(); const port 3000;//启动服务node index…...

mysql深度分页优化方案

mysql深度分页优化方案 在MySQL中&#xff0c;深度分页&#xff08;即查询大量数据中的靠后部分&#xff09;通常会导致性能问题&#xff0c;尤其是在使用 LIMIT offset, count 时。随着 offset 的增大&#xff0c;MySQL需要扫描更多的行&#xff0c;导致查询变慢。以下是一些优…...

视频教育网站开源系统的部署安装 (roncoo-education)服务器为ubuntu22.04.05

一、说明 前端技术体系&#xff1a;Vue3 Nuxt3 Vite5 Vue-Router Element-Plus Pinia Axios 后端技术体系&#xff1a;Spring Cloud Alibaba2021 MySQL8 Nacos Seata Mybatis Druid redis 后端系统&#xff1a;roncoo-education&#xff08;核心框架&#xff1a;S…...

中间件专栏之MySQL篇——MySQL缓存策略

本文所说的MySQL缓存策略与前文提到的buffer pool不同&#xff0c;那是MySQL内部自己实现的&#xff0c;本问所讲的缓存策略是使用另一个中间件redis来缓存MySQL中的热点数据。 一、为什么需要MySQL缓存方案 缓存用户定义的热点数据&#xff0c;用户可以直接从缓存中获取热点…...

CSS 日常开发常用属性总结

文章目录 CSS 日常开发常用属性总结一、 常用 CSS 属性1、布局相关&#xff08;1&#xff09;display&#xff1a;&#xff08;2&#xff09;position&#xff1a;&#xff08;3&#xff09;float&#xff1a;&#xff08;4&#xff09;clear&#xff1a; 2、尺寸与溢出&#x…...

CF 886A.ACM ICPC(Java实现)

题目分析 输入6个值&#xff0c;判断某三个值的和能够等于另外三个值的和 思路分析 首先判断总和是不是一个偶数&#xff0c;如果不是就“NO”。由于小何同学算法不好&#xff0c;只能使用三层for循环强行判断某三个值是否能等于总和的一半&#xff0c;可以就“YES”。 代码 …...

Spring Boot 自动装配深度解析与实践指南

目录 引言&#xff1a;自动装配如何重塑Java应用开发&#xff1f; 一、自动装配核心机制 1.1 自动装配三大要素 1.2 自动装配流程 二、自定义自动配置实现 2.1 创建自动配置类 2.2 配置属性绑定 2.3 注册自动配置 三、条件注解深度应用 3.1 常用条件注解对比 3.2 自定…...

【windows driver】 开发环境简明安装教程

一、下载路径 https://learn.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads 二、安装步骤&#xff1a; 1、安装Visual Studio IDE 笔者建议安装最新版本&#xff0c;可以向下兼容。发文截止到目前&#xff0c;VS2022是首选&#xff0c;当前笔者由于项…...

探秘基带算法:从原理到5G时代的通信变革【八】QAM 调制 / 解调

文章目录 2.7 QAM 调制 / 解调2.7.1 概述2.7.2 星座图星座图的结构与性能发射端的信息编码与接收端的解码差分编码的分类与实现差分编码的模4格雷加法器公式16QAM星座图与映射关系 2.7.3 信号表达式正交振幅调制的基本原理与系统分析相位误差对QAM性能的影响多电平正交振幅调制…...