Spring 是如何解决并发访问的线程安全性问题的

  springmvc的controller是singleton的(非线程安全的),这也许就是他和struts2的区别吧!和Struts同样,Spring的Controller默认是Singleton的,这意味着每一个request过来,系统都会用原有的instance去处理,这样致使了两个结果:一是咱们不用每次建立Controller,二是减小了对象建立和垃圾收集的时间;因为只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。固然大多数状况下,咱们根本不须要考虑线程安全的问题,好比dao,service等,除非在bean中声明了实例变量。所以,咱们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。 web

 

       若是控制器是使用单例形式,且controller中有一个私有的变量a,全部请求到同一个controller时,使用的a变量是共用的,即如果某个请求中修改了这个变量a,则,在别的请求中可以读到这个修改的内容。。

有几种解决方法:
一、在Controller中使用ThreadLocal变量
二、在spring配置文件Controller中声明 scope="prototype",每次都建立新的controllerspring

所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。安全

 

ThreadLocal 使用范例:多线程

 ThreadLocal<Long>startTime = newThreadLocal<Long>();  定义一个ThreadLocal 变量
并发

startTime.set(System.currentTimeMillis());   写入值
mvc

startTime.get();  读取值
spa

 

 

ThreadLocal和线程同步机制相比有什么优点呢?prototype

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。线程

在同步机制中,经过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析何时对变量进行读写,何时须要锁定某个对象,何时释放对象锁等繁杂的问题,程序设计和编写难度相对较大。设计

而ThreadLocal则从另外一个角度来解决多线程的并发访问。ThreadLocal会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。由于每个线程都拥有本身的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,能够把不安全的变量封装进ThreadLocal。

归纳起来讲,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不一样的线程排队访问,然后者为每个线程都提供了一份变量,所以能够同时访问而互不影响。

相关文章
相关标签/搜索