spring 怎么保证线程安全的

spring中管理的bean实例默认情况下是单例的[sigleton类型],就还有prototype类型
按其作用域来讲有sigleton,prototype,request,session,global session。

spring中的单例与设计模式里面的单例略有不同,设计模式的单例是在整个应用中只有一个实例,而spring中的单例是在一个IoC容器中就只有一个实例。
但spring中的单例也不会影响应用的并发访问,【不会出现各个线程之间的等待问题,或是死锁问题】因为大多数时候客户端都在访问我们应用中的业务对象,而这些业务对象并

没有做线程的并发限制,只是在这个时候我们不应该在业务对象中设置那些容易造成出错的成员变量,在并发访问时候这些成员变量将会是并发线程中的共享对象,那么这个时候

就会出现意外情况。

那么我们的Eic-server的所有的业务对象中的成员变量如,在Dao中的xxxDao,或controller中的xxxService,都会被多个线程共享,那么这些对象不会出现同步问题吗,比如会造成数据库的插入,更新异常?
还有我们的实体bean,从客户端传递到后台的controller-->service-->Dao,这一个流程中,他们这些对象都是单例的,那么这些单例的对象在处理我们的传递到后台的实体bean不会出问题吗?


答:[实体bean不是单例的],并没有交给spring来管理,每次我们都手动的New出来的【如EMakeType et = new EMakeType();】,所以即使是那些处理我们提交数据的业务处理类是被多线程共享的,但是他们处理的数据并不是共享的,数据时每一个线程都有自己的一份,所以在数据这个方面是不会出现线程同步方面的问题的。但是那些的在Dao中的xxxDao,或controller中的xxxService,这些对象都是单例那么就会出现线程同步的问题。但是话又说回来了,这些对象虽然会被多个进程并发访问,可我们访问的是他们里面的方法,这些类里面通常不会含有成员变量,那个Dao里面的ibatisDao是框架里面封装好的,已经被测试,不会出现线程同步问题了。所以出问题的地方就是我们自己系统里面的业务对象,所以我们一定要注意这些业务对象里面千万不能要独立成员变量,否则会出错。

所以我们在应用中的业务对象如下例子;
controller中的成员变量List和paperService:

public class TestPaperController extends BaseController {
private static final int List = 0;
@Autowired
@Qualifier("papersService")
private TestPaperService papersService ;
public Page queryPaper(int pageSize, int page,TestPaper paper) throws EicException{
RowSelection localRowSelection = getRowSelection(pageSize, page);
List<TestPaper> paperList = papersService.queryPaper(paper,localRowSelection);
Page localPage = new Page(page, localRowSelection.getTotalRows(),
paperList);
return localPage;
}
//service里面的成员变量ibatisEntityDao:
@SuppressWarnings("unchecked")
@Service("papersService")
@Transactional(rollbackFor = { Exception.class })
public class TestPaperServiceImpl implements TestPaperService {
@Autowired
@Qualifier("ibatisEntityDao")
private IbatisEntityDao ibatisEntityDao;
private static final String NAMESPACE_TESTPAPER = "com.its.exam.testpaper.model.TestPaper";
private static final String BO_NAME[] = { "试卷仓库" };
private static final String BO_NAME2[] = { "试卷配置试题" };
private static final String BO_NAME1[] = { "试卷试题类型" };
private static final String NAMESPACE_TESTQUESTION="com.its.exam.testpaper.model.TestQuestion";
public List<TestPaper> queryPaper(TestPaper paper,RowSelection paramRowSelection) throws EicException{
try {
return (List<TestPaper>) ibatisEntityDao.queryForListWithPage(
NAMESPACE_TESTPAPER, "queryPaper", paper,paramRowSelection);
} catch (Exception exception) {
exception.printStackTrace();
throw new EicException(exception, "eic", "0001", BO_NAME);
}
}

由上面可以看出,虽然我们这个应用里面含有成员变量,但是并不会出现线程同步方面的问题,因为,controller里面的成员变量private TestPaperService papersService ;之

所以会成为成员变量,我们的目的是注入,将其实例化进而访问里面的方法,private static final int List = 0;是final的不会被改变。
service里面的private IbatisEntityDao ibatisEntityDao;是框架本身的线程同步问题已解决【其解决方案很有可能就是使用ThreadLocal】

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值