首先直接给出答案:不是线程安全的

一、分析问题

证明不是线程安全的案例如下:

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是线程安全的吗?相关推荐

  1. Spring框架中的单例Bean是线程安全的么?

    答: 不是安全的. Spring中的Bean默认是单例模式的,框架并没有对bean进行多线程的封装处理. 注:单例bean是指IOC容器中就只有这么一个bean,是全局共享的,有多少个线程来访问用的都 ...

  2. Spring框架中的单例Bean是线程安全的吗

    Sp

  3. spring框架中的单例Beans是线程安全的么?

    看到这样一个问题:spring框架中的单例Beans是线程安全的么? Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上, ...

  4. Spring框架中的单例Beans是线程安全的么

    看到这样一个问题:Spring框架中的单例Beans是线程安全的么? Spring框架并没有对单例bean进行任何多线程的封装处理.关于单例bean的线程安全和并发问题需要开发者自行去搞定.但实际上, ...

  5. Spring 框架中的单例Beans 是线程安全的么?

    Spring 框架并没有对单例bean 进行任何多线程的封装处理.关于单例bean 的线程安全和并发问题需要开发者自行去搞定.但实际上,大部分的Spring bean 并没有可变的状态(比如Servi ...

  6. Spring源码 - 从缓存中获取单例Bean

    # Spring源码 - 从缓存中获取单例Bean Spring版本:Spring 5.3.13-release # 1.从缓存中获取单例Bean 单实例Bean在Spring的同一个容器中只会创建一 ...

  7. Spring容器中 singleton 单例、 prototype多例

    项目开发中通常会使用:singleton 单例. prototype多例 Singleton: 在一个spring容器中,对象只有一个实例.(默认值) Prototype: 在一个spring容器中, ...

  8. 面试官:Spring创建好的单例对象存在线程安全问题吗?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/jdk_wangtaida/ article/details/88738228 前言 这是我在一次面试中被问到过的问题,但是当时 ...

  9. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

最新文章

  1. 令人郁闷的 DOCTYPE
  2. Python 之父谈 Python
  3. Log4j2又爆雷!2.16.0存在DOS攻击风险,升级到2.17.0可解决!
  4. python 存入数据库bigint_【Python】从0开始写爬虫——把扒到的豆瓣数据存储到数据库...
  5. 一台服务部署多个tomcat注意事项
  6. 【cocos2d-x】游戏构成要素③----游戏关卡的实现
  7. 《计算机网络》第六章:传输层(The Transport Layer)
  8. ios aes 128 解密 php,iOS AES加密 PHP解密
  9. 用VC++建立Service服务应用程序
  10. 关于0.96OLED的显示过程详解(I2C通信方式)
  11. 日常生活小技巧 -- Beyond Compare之PC与UNIX文件比较
  12. 使照片带有妙的电影色彩55款工具套件的lr微妙的电影调色预设
  13. 栈——后入先出的数据结构(LIFO)
  14. 腾讯副总裁曾宇:谈谈腾讯的技术价值观与技术人才修炼
  15. PDF如何在线翻译?PDF在线翻译的方法
  16. redis的lru原理_Redis的LRU机制介绍
  17. 疫情之后,教育的生死淘汰赛
  18. 中文版sublime text3的下载网址和注意方法
  19. java多音字首字母排序
  20. 山水印|竹林野茶:秋冬之际,喝这些茶补水润肺

热门文章

  1. [转载] 什么是Java中的自动拆装箱 integer
  2. [转载] Python中定义函数,循环语句,条件语句
  3. python创建空元组_用Python创建空元组
  4. java 实现 堆排序算法_C程序实现堆排序算法
  5. kafka偏移量保存到mysql里_【队列】调试应用时进行的kafka偏移量调整
  6. 许多计算机英语,计算机英语翻译
  7. micropython移植教程_【教程】智能编程T-Watch手表初试micropython之电子秤教程
  8. php分布式的锁,laravel分布式并发锁
  9. 判断是否大于_电动车是否属于机动车的辩论要点
  10. scala 类中的对象是类_Scala中的类和对象