spring中的bean默认是单例的,这样如果我们写的bean是有状态的就会产生线程安全问题,有状态的bean就是指类中存在实例变量,服务器会为每个请求开一个线程,这样当一个线程修改了实例变量,另一个线程访问的变量就是被修改过的,这就是线程不安全的。
我们以controller为例,下面是测试代码
@Controller
public class testController {
private int i=0;
@RequestMapping("test")
public ModelAndView test( ){
ModelAndView mav=new ModelAndView("test");
mav.addObject("test", i++);
return mav;
}
}
前台通过${test }获取值。分别发送三次请求,前台页面取得的值为 :0 1 2
若想在线程安全情况下使用有状态的bean有以下两种方法:
第一种在@controller之前加上@Scope("prototype"),将spring中的bean改为多例。
前台通过${test }获取值。分别发送三次请求,前台页面取得的值为 : 0 0 0
第二种使用threadLocal,代码如下
@Controller
public class testController {
ThreadLocal<Integer> i=new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return 0;
};
};
@RequestMapping("test")
public ModelAndView test( ){
ModelAndView mav=new ModelAndView("test");
mav.addObject("test", i.get());
i.set(i.get()+1);
return mav;
}
}
前台通过${test }获取值。分别发送三次请求,前台页面取得的值为 : 0 0 0
,