java线程安全问题 讨论, 线程安全问题是一个值得思考的问题,有些看起来不是问题的代码,细思极恐,发现可能会出现安全问题,然后赶紧改,比如说给参数 加final 修饰。。。
其实抛开具体的问题,谈java线程安全的问题都是不严格的,对方说这是线程不安全的,我也可以说是线程安全的。比如我们常说的 ThreadLocal,大家都说他是线程不安全的,其实这个不安全是指在特定的场景下,才会发生内存泄露,线程不安全的问题。大部分情况下ThreadLocal都是安全的,否则作者当初设计这个类的时候,知道他是不安全的,那为啥还明知故犯,设计出来呢。只是使用者在使用的时候导致线程不安全的问题,我们才说ThreadLocal是线程不安全的,长久以往,脑海中先入为主,看到 ThreadLocal就映射出 它是线程不安全的 。
线程安全性问题,我们设想一下,假如一个类没有成员变量,那么这个类创建出来的对象,即使被多个线程使用——调用对象中的方法,也不会出现线程安全问题,因为多个线程之间不存储共享数据。
spring mvc、structs 关于线程安全的讨论,脑海中突然涌现一个问题: 一直说structs2 中的action是线程安全的,原因是每次请求都会创建一个 action实例,那如果 structs2和spring整合,action实例还是线程安全的吗 ?或者说 structs2中action实例是原型模式,而ioc中默认bean对象都是单例模式,这。。。是不是矛盾了,那到底 structs2 整合spring后 action 到底是单例的还是原型的。
我们回顾下: structs, structs2, 以及spring mvc
1. struts1中的action也是单实例的,每次request 请求,使用的都是 同一个action实例,如果这个action实例对象中有共用的成员变量,多个请求(多个线程)同时访问该action中的同一方法的时候,这个成员变量就会有线程安全的问题,所以使用的时候会有线程安全问题。如果没有共用的属性、成员变量,线程之间没有数据共用是不会发生线程安全的。
2. struts2中的action会为每个请求产生一个action实例(原型模式),所以不存在线程安全问题。
3. spring mvc 中的Controller(handler)也是单例的(单例模式),和上面的structs1 中的action是类似的,如果这个Controller实例对象中有共用的成员变量,多个请求(多个线程)同时访问该controller中的同一方法的时候,这个成员变量就会有线程安全的问题,所以使用的时候会有线程安全问题。如果没有共用的属性、成员变量,线程之间没有数据共用是不会发生线程安全的。
4. 如果structs2 和spring 框架整合,想把action实例通过spring ioc容器管理,由于默认spring ioc创建的bean对象都是单例的,所以这种方式默认创建的structs2 action实例也是单例的,如果要实现原型的,需要在Action类 scope设置为prototype 属性。
5. 在说说 spring mvc中的核心类——DispatcherServlet ,这个类是在spring 容器启动的时候,会创建相应的bean对象,放在ioc容器中,默认也是单例的,每次请求(每个线程访问)都要经过这个对象的service()方法,看起来 DispatcherServlet bean对象也是线程不安全的,但是实际上,请求都是交个相应的 handler处理(controller处理),每个请求相互没有共用的成员变量,所以可以认为 DispatcherServlet bean对象是 线程安全的。

本文探讨Java线程安全问题及Spring MVC、Struts框架中的线程安全实践。分析了ThreadLocal、Struts2与Spring整合时的线程安全问题,并对比了Spring MVC与Struts1/2的线程安全特性。


被折叠的 条评论
为什么被折叠?



