springMVC负责的controller层的类默认是单例模式的,单例模式少去了重复创建对象,垃圾内存回收的过程,在性能方面有一些提升。
但是,http请求往往是同时多个请求进来的,这样就会开启多个线程来运行controller,那controller在单例模式下,类中定义的属性那些是线程安全的呢?那些是线程不安全的呢?
做了以下几个测试:
package com.lee.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.lee.model.Single;
import com.lee.model.UserPo;
import com.lee.service.UserService;
@Controller
@RequestMapping(value="/")
public class UserController {
final static Logger logger = LoggerFactory.getLogger(UserController.class);
private int i; //基本数据类型 线程不安全的
@Autowired
private UserService userServiceImpl; //service层 包括下面的dao层 线程安全的
@Autowired
private HttpServletRequest httpServletRequest; //线程安全的
@Autowired
private Single single; //引用数据类型 线程不安全的
@RequestMapping("/single_test")
public @ResponseBody void single(@RequestBody UserPo userPo) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String parameter = httpServletRequest.getParameter("name");
String id = httpServletRequest.getSession().getId();
// single = new Single();
/*logger.debug("{} single", userPo.getUserId());
single.setJ(Integer.valueOf(userPo.getUserId()));
single.setStr("lee " +userPo.getUserId());*/
//UserPo userPo2 = userServiceImpl.getUserPo(userPo.getUserId());
/*try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
// logger.debug(userPo.getUserId() + " name = " + userPo2.getUserName());
// logger.debug(userPo.getUserId() + " id = " + userPo2.getUserId());
// logger.debug(userPo.getUserId() + " age = " + userPo2.getUserAge());
/*logger.debug(userPo.getUserId()+ " j = " +single.getJ());
logger.debug(userPo.getUserId()+ " str = " +single.getStr());*/
//logger.debug("id = " +userPo.getUserId());
logger.debug(userPo.getUserId() + " parameter = " +parameter);
logger.debug(userPo.getUserId() + " sessionid = " +id);
}
}
发现controller类里的属性:
1.基本数据类型是线程不安全的,线程共用
2.service、dao层是线程安全的
3.HttpServletRequest是线程安全的
4.普通的pojo也是线程不安全的
我以为spring管理的类,就算当controller类的属性也是线程安全的,但不知道为什么Single类做为属性不是线程安全的。
controller内的方法中定义的变量(包括方法参数)也就是局部变量是线程安全的。
如果不想让controller类是单例模式,就在controller类上面加上@Scope("prototype"),这样每一次请求spring都会生成一个新的对象,就不存在线程安全的问题了。
测试不知道严不严谨,希望大家指证。