java spring mvc 线程安全
2017-04-26 11:15
141 查看
在spring 框架当中,默认每个bean 都是scope=”singleton”单例模式。即是只在首次创建该类的实例,之后所用引用的该bean,其实都是首次创建的实例。
所以当多个线程同时操作该bean的时候,就有可能出现线程不安全的情况(主要体现在该bean拥有属性,且在运行中会更改该属性的时候)。
spring mvc 中如果我们没有对该类进行修饰指定的话,也默认是scope=”sington”单例模式。如果该类存在着自我属性的话也容易触发线程安全问题,从而导致出现脏数据的情况。
那么,我们怎么去解决这个问题呢?
1、spring mvc 官方推荐我们使用单例模式,因为单例模式下不用用户每次请求都重新生成一个实例,所以性能很好。所以我们应避免在bean中定义属性
2、如果项目需求需要定义属性,那么我们就需要更改scope=”sington”单例模式为scope=”prototype”原型模式,这种模式在每次引用该bean的时候都会重新生成一个该bean的对象,所以不会存在线程安全问题了。还有一种模式,是spring针对web开发衍生的scope=”request”模式,这种模式是将实例保存在request作用域中,所以每个请求即是每个线程都有独自属于自己的bean 也是线程安全,但是针对前一个scope=”prototype” 安全性没有那么高,为啥?因为是保存在request作用域中的。所以除了首次调用会生成该实例,之后每次调用都是从request作用域中取出来的,而不像scope=”prototype”每次调用都会实例化一个新的对象给你。
如上,将类DemoService 修饰@Scope(“request”)那么每次用户请求都会生成该类的实例,之后,不管是在哪一个组件下面调用都不会再生成该类的实例,而是直接引用保存在request作用域中的实例。当然,你重新加载了这个类并实例化除外,只能是通过spring 去调用交给spring去处理。如我就喜欢将数据库连接和操作写成request作用域,每个用户请求生成一个数据库连接,当用户关闭页面后就通过@PreDestroy修饰的方法去关闭数据库连接。
所以当多个线程同时操作该bean的时候,就有可能出现线程不安全的情况(主要体现在该bean拥有属性,且在运行中会更改该属性的时候)。
spring mvc 中如果我们没有对该类进行修饰指定的话,也默认是scope=”sington”单例模式。如果该类存在着自我属性的话也容易触发线程安全问题,从而导致出现脏数据的情况。
那么,我们怎么去解决这个问题呢?
1、spring mvc 官方推荐我们使用单例模式,因为单例模式下不用用户每次请求都重新生成一个实例,所以性能很好。所以我们应避免在bean中定义属性
2、如果项目需求需要定义属性,那么我们就需要更改scope=”sington”单例模式为scope=”prototype”原型模式,这种模式在每次引用该bean的时候都会重新生成一个该bean的对象,所以不会存在线程安全问题了。还有一种模式,是spring针对web开发衍生的scope=”request”模式,这种模式是将实例保存在request作用域中,所以每个请求即是每个线程都有独自属于自己的bean 也是线程安全,但是针对前一个scope=”prototype” 安全性没有那么高,为啥?因为是保存在request作用域中的。所以除了首次调用会生成该实例,之后每次调用都是从request作用域中取出来的,而不像scope=”prototype”每次调用都会实例化一个新的对象给你。
package spring.beans.service; @Service("service_demo") @Scope("request") public class DemoService { }
import spring.beans.service.DemoService; @Service @RequestMapping("Demo2") @Scope("request") public class Demo2Controller { @Resource(name="service_demo") private DemoService demoService; @RequestMapping(value="index",method=RequestMethod.GET,produces="text/html;charset=utf-8") @ResponseBody public String getIndex() { return "hello world"; } }
如上,将类DemoService 修饰@Scope(“request”)那么每次用户请求都会生成该类的实例,之后,不管是在哪一个组件下面调用都不会再生成该类的实例,而是直接引用保存在request作用域中的实例。当然,你重新加载了这个类并实例化除外,只能是通过spring 去调用交给spring去处理。如我就喜欢将数据库连接和操作写成request作用域,每个用户请求生成一个数据库连接,当用户关闭页面后就通过@PreDestroy修饰的方法去关闭数据库连接。
相关文章推荐
- Java Web层框架比较—— 比较JSF、Spring MVC、Stripes、Struts 2、Tapestry和Wicket
- 破除java神话之三:原子操作都是线程安全的
- java 线程安全
- java 线程安全 safety failure & liveness failure
- 为什么Java中的long与double不是线程安全的?
- Java Web框架比较——JSF、Spring MVC、Stripes、Struts 2、Tapestry和Wicket
- Java Web层框架——JSF、Spring MVC、Stripes、Struts 2、Tapestry和Wicket
- Java并行(4):线程安全前传之Singleton
- 随手笔记: Java中Static List同步线程安全解决办法
- java的线程安全
- Java:什么是线程安全
- 对java中File.mkdirs方法线程安全问题的一点探讨
- Java 集合 线程安全
- 破除java神话之三:原子操作都是线程安全的
- [导入]java的线程安全
- java实现线程安全的三大利器
- JAVA 线程安全 秘笈
- java 成员变量的线程安全
- 为什么Java中的long与double不是线程安全的?
- Java 线程安全