关于struts 1 中的线程问题


今天突然发现几个月前写的代码中的一个线程问题.在这里做个笔记:

因为在struts1中在整个web生命周期中,web服务器只为每个action产生一个实例,所以就会产生线程问题,就必须要编写线程安全的代码.

需求是这样,简单的来说我需要保存一个学生的一些信息,但之前我需要加载这个学生相关的一些信息,信息量很大,然后在这些信息中筛选出需要的保存起来.关键在于这个加载的过程,因为信息量比较大所以我想怎么能够尽量提高它的效率.

我最开始的想法:能够在用户进入保存页面的时候先预先把学生信息加载好,然后用户在保存的时候就能够只做保存的事情,也就是把本来该一个动作做的事情分开城两个动作来做.这样来提升用户的体验.

service层中的代码:

public class LoadStudentWccDataService { private static LoadStudentWccDataService instance; private static String studKey; private Map modelMap =new HashMap(); private LoadStudentWccDataService(String studKey, UserInfo userInfo) throws ApplicationException { loadWccDataByStudentKey(studKey, userInfo); } public static LoadStudentWccDataService getInstance(String studentKey, UserInfo userInfo) throws ApplicationException { if (instance ==null || !studentKey.equals(studKey)) { studKey=studentKey; instance= new LoadStudentWccDataService(studentKey, userInfo); } return instance; } public Object getModelByModelType(String modelType) { return modelMap.get(modelType); } private void loadWccDataByStudentKey(String StudKey, UserInfo userInfo) throws ApplicationException { ..............//加载学生信息到map中 }

这样的话不会每次加载学生信息的时候都新建一个对象,同一个student就不用加载了

每次进保存页面的时候执行getInstance加载信息,保存的时候就执行getModelByModelType,取出加载的性息.

我满心欢喜,以为自己在达到需求的同时又兼顾了效率.但是现在看来却有重大的问题.

我从开始考虑到写出的代码都没有考虑多线程的情况

一个学生进入了保存页面,执行了getInstance,在保存之前另一个学生又进来了,重新执行了getInstance,这样就把上个学生的信息覆盖了,最后两个学生保存的都是后一个学生的信息.

怎么改呢?

首先想到的是线程同步,我把这个类所有的方法都加上synchronized,这个在同一个时间只能有一个学生调用这个类的方法,其他都得排队(这里要把所有的方法都加synchronized,因为锁是针对class的,一个线程调用了这个类中的一个同步方法,那么其他线程在同一时间不能调用任何一个同步方法).但这也没对.

因为我把加载信息和保存信息在serviece中放成两个方法,这样就算同步了方法也会造成问题.

怎么办,1)是把加载信息和保存信息在service中放成一个方法,这样就可以用同步来解决问题.

2)是每次getInstance的时候都生成了一个新的对象,也不会有问题

最终我选择了第2种,没错,效率比较低,不过在这种情况下我也实在想不出两全其美的办法,如果谁有更好的方法希望提出来.

 

总结,在struts1中要特别注意线程问题,也就是你编写的类最好是非可变类,所谓非可变类就是你的方法中不要有各个方法之间共享的变量,如上面的studKey.即使有也要加上final让它成为只读的.

如果不是则很容易产生线程问题

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值