spring框架在service层加上@service注解是单例模式, 两个线程同时调用单例模式service, 线程1的service的test方法返回1; 线程2的service的test方法返回2; 返回到controller的时候会不会拿到的都是2 ; 不会搞混吗?
为了说明问题,画个简单的JVM运行时数据区。
Spring框架在service层加上@Service注解是单例模式:注意:Spring默认是单例模式。
说明:下面的描述是在非线程安全的前提下做出的解释。
1、看上面的图,用注解@Service修饰的类,比如Test类,是单例的,也就是说,Controller层调用Test类,调用的是同一个对象。
2、重点来了,注意:方法test() 是在虚拟机栈里面运行的,当线程1调用方法test的时候,会在虚拟机栈里面开辟一个空间,线程2同理。
3、两个线程调用不同的空间,当然返回值也不同。
稍微扩展一下:在有线程安全的环境下:
假如线程1和线程2要操作相同的资源,或者凡是有线程安全问题存在,你提的问题就会发生。
首先要了解Spring Bean的作用域:
singleton:默认方式,单例模式,每个容器只有一个实例。
prototype:原型模式,每次获取(请求)Bean都创建一个实例。
request:为每一个网络请求创建一个实例,请求结束后Bean会失效并被辣鸡回收。
session:与request有点类似,在新建一个新的http会话的时候会创建一个Bean实例,确保每个session有个bean,并且bean在session失效后随之失效。
global Session:在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。
spring默认都是单例bean所以是都会被多个线程访问同一个Bean所以是线程不安全的。如果bean中存在共享变量,那么这些变量就会产生线程不安全问题。
单例跟变量没关系啊 每个方法内的变量都存储在局部变量表里,是线程独享的 不会出现冲突的
1.spring默认是单例的,但是跟@service注解没有关系。单例还是多例跟@Bean注解有关系,通过scope属性进行设置,scope取值有
scope="singleton",单例(默认);
scope="prototype",任何一个实例都是新的实例;
scope="request",在WEB应用程序中,每一个实例的作用域都为request范围;
scope="session",在WEB应用程序中,每一个实例的作用域都为session范围;
2.你说的会不会搞混的问题是不存在的,即使调用同一个类同一个方法,方法里的局部变量都是线程私用的,大家互不影响。