Spring框架中的单例Bean是线程安全的吗?
首先直接给出答案:不是线程安全的
一、分析问题
证明不是线程安全的案例如下:
public class Student {private String stuName;public String report(String uname){stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;}
}
-----------------------------------------------------------------------------------------------------------------
public class Run {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);Student bean1 = context.getBean(Student.class);new Thread(() -> {System.out.println(bean1.report("张三"));}).start();Student bean2 = context.getBean(Student.class);new Thread(() -> {System.out.println(bean2.report("李四"));}).start();}
}
分析原因:线程一执行完stuName的赋值后进入休眠,线程二这时候也进入该方法对stuName进行赋值,由于对象是单例的,线程二的赋值操作也就影响了线程一的打印结果。导致最后打印的结果都是线程二传入的值。
二、解决方法
既然单例bean不是线程安全的,那么该怎么解决上面的问题呢?下面博主给出四种解决方法仅供读者参考:
1.方法一:将成员变量放入方法中
修改后的Student类如下:
public class Student {// private String stuName;public String report(String uname){String stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;}
}
2.方法二:加锁使方法串行执行
比如下面的方法中我加入了synchronized锁:
public class Student {private String stuName;public synchronized String report(String uname){stuName = "大家好,我叫:"+uname;try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName;}
}
3.方法三:将bean变成原型模式
比如加上Scope注解声明为多例模式:
@Bean@Scope("prototype")public Student student(){return new Student();}
4.方法四:使用ThreadLocal
改造后的代码如下:
public class Student {private ThreadLocal<String> stuName = new ThreadLocal<>();public String report(String uname){stuName.set("大家好,我叫:"+uname);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return stuName.get();}
}
Spring框架中的单例Bean是线程安全的吗?相关推荐
- Spring框架中的单例Bean是线程安全的么?
答: 不是安全的. Spring中的Bean默认是单例模式的,框架并没有对bean进行多线程的封装处理. 注:单例bean是指IOC容器中就只有这么一个bean,是全局共享的,有多少个线程来访问用的都 ...
- Spring框架中的单例Bean是线程安全的吗
Sp
- spring框架中的单例Beans是线程安全的么?
看到这样一个问题:spring框架中的单例Beans是线程安全的么? Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上, ...
- Spring框架中的单例Beans是线程安全的么
看到这样一个问题:Spring框架中的单例Beans是线程安全的么? Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上, ...
- Spring 框架中的单例Beans 是线程安全的么?
Spring 框架并没有对单例bean 进行任何多线程的封装处理.关于单例bean 的线程安全和并发问题需要开发者自行去搞定.但实际上,大部分的Spring bean 并没有可变的状态(比如Servi ...
- Spring源码 - 从缓存中获取单例Bean
# Spring源码 - 从缓存中获取单例Bean Spring版本:Spring 5.3.13-release # 1.从缓存中获取单例Bean 单实例Bean在Spring的同一个容器中只会创建一 ...
- Spring容器中 singleton 单例、 prototype多例
项目开发中通常会使用:singleton 单例. prototype多例 Singleton: 在一个spring容器中,对象只有一个实例.(默认值) Prototype: 在一个spring容器中, ...
- 面试官:Spring创建好的单例对象存在线程安全问题吗?
点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/jdk_wangtaida/ article/details/88738228 前言 这是我在一次面试中被问到过的问题,但是当时 ...
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
最新文章
- 令人郁闷的 DOCTYPE
- Python 之父谈 Python
- Log4j2又爆雷!2.16.0存在DOS攻击风险,升级到2.17.0可解决!
- python 存入数据库bigint_【Python】从0开始写爬虫——把扒到的豆瓣数据存储到数据库...
- 一台服务部署多个tomcat注意事项
- 【cocos2d-x】游戏构成要素③----游戏关卡的实现
- 《计算机网络》第六章:传输层(The Transport Layer)
- ios aes 128 解密 php,iOS AES加密 PHP解密
- 用VC++建立Service服务应用程序
- 关于0.96OLED的显示过程详解(I2C通信方式)
- 日常生活小技巧 -- Beyond Compare之PC与UNIX文件比较
- 使照片带有妙的电影色彩55款工具套件的lr微妙的电影调色预设
- 栈——后入先出的数据结构(LIFO)
- 腾讯副总裁曾宇:谈谈腾讯的技术价值观与技术人才修炼
- PDF如何在线翻译?PDF在线翻译的方法
- redis的lru原理_Redis的LRU机制介绍
- 疫情之后,教育的生死淘汰赛
- 中文版sublime text3的下载网址和注意方法
- java多音字首字母排序
- 山水印|竹林野茶:秋冬之际,喝这些茶补水润肺
热门文章
- [转载] 什么是Java中的自动拆装箱 integer
- [转载] Python中定义函数,循环语句,条件语句
- python创建空元组_用Python创建空元组
- java 实现 堆排序算法_C程序实现堆排序算法
- kafka偏移量保存到mysql里_【队列】调试应用时进行的kafka偏移量调整
- 许多计算机英语,计算机英语翻译
- micropython移植教程_【教程】智能编程T-Watch手表初试micropython之电子秤教程
- php分布式的锁,laravel分布式并发锁
- 判断是否大于_电动车是否属于机动车的辩论要点
- scala 类中的对象是类_Scala中的类和对象