Is the thread safe of springmvc's control thread safe?

About the thread safety of java Servlet, Struts, springMVC

Now the mainstream java front-end frameworks are: struts1, struts2, springmvc and the most fundamental servlet;

A friend asked me this question a few days ago, so I did some research:

1. About struts1:

The ActionServlet used by Struts1 is a singleton, and all .do requests are handled by this servlet. RequestProcessor is also a singleton.

ProcessActionCreate method of RequestProcessor:

/**
  * <p>Return an <code>Action</code> instance that will be used to process
  * the current request, creating a new one if necessary.</p>
  *
  * @param request  The servlet request we are processing
  * @param response The servlet response we are creating
  * @param mapping  The mapping we are using
  * @return An <code>Action</code> instance that will be used to process
  *		 the current request.
  * @throws IOException if an input/output error occurs
  */
 protected Action processActionCreate(HttpServletRequest request,
 HttpServletResponse response, ActionMapping mapping)
 throws IOException {
 // Acquire the Action instance we will be using (if there is one)
 String className = mapping.getType();
 if (log.isDebugEnabled()) {
 log.debug(" Looking for Action instance for class " + className);
 }
 Action instance;
 // This synchronization guarantees that Action's singleton is 
 synchronized (actions) {
  // Return any existing Action instance of this class
 instance = (Action) actions.get(className);
 if (instance != null) {
 if (log.isTraceEnabled()) {
 log.trace("  Returning existing Action instance");
 }
 return (instance);
 }
 // Create and return a new Action instance
 if (log.isTraceEnabled()) {
 log.trace("  Creating new Action instance");
 }
 try {
 instance = (Action) RequestUtils.applicationInstance(className);
 // Maybe we should propagate this exception
 // instead of returning null.
 } catch (Exception e) {
 log.error(getInternal().getMessage("actionCreate",
 mapping.getPath()), e);
 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
 getInternal().getMessage("actionCreate", mapping.getPath()));
 return (null);
 }
 actions.put(className, instance);
 if (instance.getServlet() == null) {
 instance.setServlet(this.servlet);
 }
 }
 return (instance);
 }

It can be known from the results that it is a singleton. Since it is a singleton, if instance variables are used, there will be thread safety problems;

 

2. About struts2

 

We know that when we use struts2, we use actionContext; we all use the instance variables inside, so that struts2 automatically matches into objects.  If it is not thread-safe, it is all over; so struts2 must be thread-safe;  because every time a request is processed, struts will instantiate an object; so there will be no thread-safety issues; 

Oh, I forgot a situation, when struts2+spring manages the injection; if the action is set to a singleton mode, there will be problems; you can set the action to the prototype type, and another way is to set the scope (specifically no experimented)

Reference source

3. About SpringMVC

SpringMVC's controller is singleton mode by default, so there will be multi-threaded concurrency problems;

Reference Code:

@RequestMapping("/user")
@Controller
Class UserController
{
@Resource
UserService userService;

@RequestMapping("/add")
public void testA(User user){
userService.add(user);
}

@RequestMapping("/get")
public void testA(int id){
userService.get(id);
}
}

@Service("userService")
Class UserService{

public static Map<Integer,User> usersCache = new HashMap<String,User>();

public void add(User user){
usersCache.put(user.getId(),user);
}

public void get(int id){
usersCache.get(id);
}

}

usersCache就是非线程安全的。

解决方法:

1)同步共享数据

2)不使用成员实例变量;

3)使用只读数据

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326593812&siteId=291194637