职面 | 面试官:Spring 中的 bean 是线程安全的吗

职面 | 面试官:Spring 中的 bean 是线程安全的吗,第1张

面试官经常喜欢问Spring中的bean是不是线程安全的这个问题用来考察对Spring 中Bean作用域的理解,先说结论, Spring中的Bean不是线程安全的

Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体还是要结合具体scope的Bean去研究。

Spring 的 bean 作用域(scope)类型有5种:

线程安全这个问题,要从单例与原型Bean分别进行说明。

原型Bean 对于原型Bean,每次创建一个新对象,也就是线程之间并不存在Bean共享,自然是不会有线程安全的问题。

单例Bean 对于单例Bean,所有线程都共享一个单例实例Bean,因此是存在资源的竞争。

如果单例Bean,是一个无状态Bean,也就是线程中的 *** 作不会对Bean的成员执行 查询 以外的 *** 作,那么这个单例Bean是线程安全的。

Spring中的Bean默认是单例模式的,框架并没有对bean进行多线程的封装处理。实际上大部分时间Bean是无状态的(比如Dao) 所以说在某种程度上来说Bean其实是安全的。

但是如果Bean是有状态的 那就需要开发人员自己来进行线程安全的保证,最简单的办法就是改变bean的作用域 把 singleton 改为 protopyte , 这样每次请求Bean就相当于是 new Bean() 这样就可以保证线程的安全了。

有状态就是有数据存储功能 无状态就是不会保存数据

controller、service和dao层本身并不是线程安全的,只是如果只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制变量,这是自己的线程的工作内存,是安全的。

想理解原理可以看看《深入理解JVM虚拟机》,222节:

《Java并发编程实战》第322节:

所以其实任何无状态单例都是线程安全的。Spring的根本就是通过大量这种单例构建起系统,以事务脚本的方式提供服务

也可以看看这篇加深理解:[关于Spring的@Controller @Service等的线程安全问题],地址: >public class GetApplicationContext {

private static class ApplicationContextHolder {

// 单例变量

private static ApplicationContext AC = new FileSystemXmlApplicationContext(

"classpath:applicationContextxml");

}

// 私有化的构造方法,保证外部的类不能通过构造器来实例化。

private GetApplicationContext() {

}

// 获取单例对象实例

public static ApplicationContext getInstance() {

if (ApplicationContextHolderAC == null) {

ApplicationContextHolderAC = new FileSystemXmlApplicationContext(

"classpath:applicationContextxml");

}

return ApplicationContextHolderAC;

}

}

获取所有spring自动装配的bean:

<span style="font-size:18px;">//获取spring装配的bean个数

GetApplicationContextgetInstance()getBeanDefinitionNames()length;

//逐个打印出spring自动装配的bean。根据我的测试,类名第一个字母小写即bean的名字

for(int i=0;i<33;i++){

Systemoutprintln( GetApplicationContextgetInstance()getBeanDefinitionNames()[i]);

}</span>

然后通过下面的代码获取到spring注解装配的bean供自己使用:

<span style="font-size:18px;">StorageReturnService ossService = (StorageReturnService) GetApplicationContextgetInstance()getBean("storageReturnServiceImpl");</span>

你可以不用单例模式

Spring支持如下五种作用域:

singleton: 单例模式,在整个Spring IoC容器中,singleton作用域的Bean将只生成一个实例。

prototype: 每次通过容器的getBean()方法获取prototype作用域的Bean时,都将产生一个新的Bean实例。

request: 对于一次>

ThreadcurrentThread()是得到当前运行的线程名,如果你不停的切换线程自然会变,还有ThreadLocal也是会跟着变的。 你要永远记着,每个线程都有自己对应的ThreadLocal,TL只是Thread的局部变量。

以上就是关于职面 | 面试官:Spring 中的 bean 是线程安全的吗全部的内容,包括:职面 | 面试官:Spring 中的 bean 是线程安全的吗、如何获取spring 注解的bean、spring的bean一般是单例模式,那多线程是怎么解决的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9595206.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存