联系我们 - 广告服务
您的当前位置:官网首页 > 资讯 > 热评 >

Spring的并发问题

来源: 编辑: 时间:2019-09-11
导读: singleton表示该bean全局只有一个实例。prototype表示该bean在每次被注入的时候,都要重新创建一个实例,这种情况适用于有状态的bean。 如......

singleton表示该bean全局只有一个实例。

prototype表示该bean在每次被注入的时候,都要重新创建一个实例,这种情况适用于有状态的bean。

 

如果对有状态的bean使用了singleton的话会出现线程安全问题。

例如上面的例子

如果有两个用户同时访问

假定为user1,user2

当user1 调用到程序中的1步骤的时候,该bean的私有变量user被付值为user1

当user1的程序走到2步骤的时候,该bean的私有变量user被重新付值为user1_create

理想的状况,当user1走到3步骤的时候,私有变量user应该为user1_create;

但如果在user1调用到3步骤之前,user2开始运行到了1步骤了,由于单态的资源共享,则私有变量user被修改为user2

这种情况下,user1的步骤3用到的user.getid实际用到是user2的对象。



对于这种情况我们可以这样解决

1.将有状态的bean配置成prototype模式,让每一个线程都创建一个prototype实例。但是这样会产生很多的实例消耗较多的内存空间。

2.使用threadlocal变量,为每一条线程设置变量副本。

 

使用threadlocal的例子:

例如,我们有一个银行的bankdao类和一个个人账户的peopledao类,现在需要个人向银行进行转账,在peopledao类中有一个账户减少的方法,bankdao类中有一个账户增加的方法,那么这两个方法在调用的时候必须使用同一个凯发官网connection数据库连接对象,如果他们使用两个connection对象,则会开启两段事务,可能出现个人账户减少而银行账户未增加的现象。使用同一个connection对象的话,在应用程序中可能会设置为一个全局的数据库连接对象,从而避免在调用每个方法时都传递一个connection对象。问题是当我们把connection对象设置为全局变量时,你不能保证是否有其他线程会将这个connection对象关闭,这样就会出现线程安全问题。解决办法就是在进行转账操作这个线程中,使用threadlocal中获取connection对象,这样,在调用个人账户减少和银行账户增加的线程中,就能从threadlocal中取到同一个connection对象,并且这个connection对象为转账操作这个线程独有,不会被其他线程影响,保证了线程安全性。

public class connectionholder {
 public static threadlocal connection connectionholder = new threadlocal connection  {
 public static connection getconnection{
 connection connection = connectionholder.get;
 if{
 connection = drivermanager.getconnection;
 connectionholder.set;
 return connection;
}

参考自:

 

责任编辑:

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

上一篇:SSH框架之Hibernate第一篇
下一篇:没有了

网友评论:

在“\templets\demo\comments.htm”原来的内容全部删除,插入第三方评论代码,如果不需要评论功能,删除comments.html里面的内容即可
推荐使用友言、多说、畅言(需备案后使用)等社会化评论插件

Copyright © 2018 凯发vip凯发vip-凯发vip网址-凯发官网 All Rights Reserved Power by DedeCms
本站所有资讯来源于网络 如有侵权请联系QQ:9490489
Top