Struts1,Struts2,springmvc,servlet线程安全问题

Struts1线程不安全

/**
  * 

Return an Action instance that will be used to process * the current request, creating a new one if necessary.

* * @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 Action 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; // 这个同步快保证了Action的单例 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); }

在一个应用的生命周期中,Struts框架只会为每个Action类创建一个Action实例(与servlet是一样的)。所有的客户请求共享一个Action实例,并且所有请求线程可以同时执行它的execute()方法。
所以,每个action只有一个实例, 在action打印this也可以看到, 确实是一样的,
所以,
不要在Action里面使用全局变量记忆数据, 没有意义而且不安全

Struts2线程安全

因为每次处理一个请求,struts就会实例化一个对象

如果在spring注入action时使用了单例,也会导致线程不安全

对于使用过SpringMVC和Struts2的人来说,大家都知道SpringMVC是基于方法的拦截,而Struts2是基于类的拦截。

对于Struts2来说,因为每次处理一个请求,struts就会实例化一个对象;这样就不会有线程安全的问题了;
而Spring的controller默认是Singleton的,这意味着每一个request过来,系统都会用原有的instance去处理,这样导致两个结果:
一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。

servlet和springmvc都是线程不安全

如果要让struts1,springmvc,servlet都变成线程安全该怎么做
1.与Spring集成@Scope("prototype"),对应每次请求产生一个新的action实例。
2.加锁

当然这些讨论都针对实例变量,如果action中共享的是静态变量,单例不单例都线程不安全了。

你可能感兴趣的:(Struts1,Struts2,springmvc,servlet线程安全问题)