SpringBoot单实例与线程安全总结
⼀、Spring单例模式与线程安全
Spring框架⾥的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地⽅。
单例模式的意思就是只有⼀个实例。单例模式确保某⼀个类只有⼀个实例,⽽且⾃⾏实例化并向整个系统提供这个实例。这个类称为单例类。
当多⽤户同时请求⼀个服务时,容器会给每⼀个请求分配⼀个线程,这是多个线程会并发执⾏该请求多对应的业务逻辑(成员⽅法),此时就要注意了,如果该处理逻辑中有对该单列状态的修改(体现为该单列的成员属性),则必须考虑线程同步问题
同步机制的⽐较  ThreadLocal和线程同步机制相⽐有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
  在同步机制中,通过对象的锁机制保证同⼀时间只有⼀个线程访问变量。这时该变量是多个线程共享的,使⽤同步机制要求程序慎密地分析什么时候对变量进⾏读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较⼤。
  ⽽ThreadLocal则从另⼀个⾓度来解决多线程的并发访问。ThreadLocal会为每⼀个线程提供⼀个独⽴的变量副本,从⽽隔离了多个线程对数据的访问冲突。因为每⼀个线程都拥有⾃⼰的变量副本,从⽽也就没有必要对该变量进⾏同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
 概括起来说,对于多线程资源共享的问题,同步机制采⽤了“以时间换空间”的⽅式,⽽ThreadLocal采⽤了“以空间换时间”的⽅式。前者仅提供⼀份变量,让不同的线程排队访问,⽽后者为每⼀个线程都提供了⼀份变量,因此可以同时访问⽽互不影响。
⼆、Spring线程安全
线程安全问题都是由全局变量(成员变量)及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,⽽⽆写操作,⼀般来说,这个全局变量是线程安全的;若有多个线程同时执⾏写操作,⼀般都需要考虑线程同步,否则就可能影响线程安全。
1) 常量始终是线程安全的,因为只存在读操作。
2)每次调⽤⽅法前都新建⼀个实例是线程安全的,因为不会访问共享的资源。
3)局部变量是线程安全的。因为每执⾏⼀个⽅法,都会在独⽴的空间创建局部变量,它不是共享的资源。局部变量包括⽅法的参数变量和⽅法内变量。
springboot框架的作用有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象  ,可以保存数据,是⾮线程安全的。在不同⽅法调⽤间不保留任何状态。
⽆状态就是⼀次操作,不能保存数据。⽆状态对象(Stateless Bean),就是没有实例变量的对象  .不能保存数据,是不变类,是线程安全的。
有状态对象:
⽆状态的Bean适合⽤不变模式,技术就是单例模式,这样可以共享实例,提⾼性能。有状态的Bean,多线程环境下不安全,那么适合⽤Prototype原型模式。Prototype: 每次对bean的请求都会创建⼀个新的bean实例。
Struts2默认的实现是Prototype模式。也就是每个请求都新⽣成⼀个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的⽣命周期, scope要配成prototype作⽤域。
三、Spring线程总结:
·
Spring中DAO和Service都是以单实例的bean形式存在,Spring通过ThreadLocal类将有状态的变量(例如数据库连接Connection)本地线程化,从⽽做到多线程状况下的安全。在⼀次请求响应的处理线程中, 该线程贯通展⽰、服务、数据持久化三层,通过ThreadLocal使得所有关联的对象引⽤到的都是同⼀个变量。
·在事务属性为REQUIRED时,在相同线程中进⾏相互嵌套调⽤的事务⽅法⼯作于相同的事务中。如果互相嵌套调⽤的事务⽅法⼯作在不同线程中,则不同线程下的事务⽅法⼯作在独⽴的事务中。
·程序只要使⽤SpringDAO模板,例如JdbcTemplate进⾏数据访问,⼀定没有数据库连接泄露问题!如果程序中显式的获取了数据连接Connection,则需要⼿⼯关闭它,否则就会泄露!
·当Spring事务⽅法运⾏时,就产⽣⼀个事务上下⽂,它在本事务执⾏线程中对同⼀个数据源绑定了⼀个唯⼀的数据连接,所有被该事务上下⽂传播的⽅法都共享这个连接。要获取这个连接,如要使⽤Spirng的资源获取⼯具类DataSourceUtils。
·事务管理上下⽂就好⽐⼀个盒⼦,所有的事务都放在⾥⾯。如果在某个事务⽅法中开启⼀个新线程,新线程中执⾏另⼀个事务⽅法,则由上⾯第⼆条可知这两个⽅法运⾏于两个独⽴的事务中,但是:如果使⽤DataSourcesUtils,则新线程中的⽅法可以从事务上下⽂中获取原线程中的数据连接!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。