zoukankan      html  css  js  c++  java
  • struts1和struts2线程安全对比

    ①,Struts1通过缓存来管理action对象,并且使用了单例模式,就是一个action只产生一个实例对象,这个实例对象要处理所有对应的request,所以Action类里面不应该有可变的全局变量,我们应该把所有的变量都封装到ActionForm里面。

    来看下Struts1的生成action实例对象的源代码:

     1     protected Action processActionCreate(HttpServletRequest request,
     2         HttpServletResponse response, ActionMapping mapping)
     3         throws IOException {
     4         // 获取action类的名字
     5         String className = mapping.getType();
     6 
     7         if (log.isDebugEnabled()) {
     8             log.debug(" Looking for Action instance for class " + className);
     9         }
    10 
    11         Action instance;
    12         
    13         // 加锁处理。
    14         synchronized (actions) {
    15             // 如果此Action已经被创建过对象了,则直接返回已经创建好的对象。
    16             instance = (Action) actions.get(className);
    17 
    18             if (instance != null) {
    19                 if (log.isTraceEnabled()) {
    20                     log.trace("  Returning existing Action instance");
    21                 }
    22 
    23                 return (instance);
    24             }
    25 
    26             // 如果还没有被创建对象,则创建一个再返回。
    27             if (log.isTraceEnabled()) {
    28                 log.trace("  Creating new Action instance");
    29             }
    30 
    31             try {
    32                 instance = (Action) RequestUtils.applicationInstance(className);
    33 
    34                 // Maybe we should propagate this exception
    35                 // instead of returning null.
    36             } catch (Exception e) {
    37                 log.error(getInternal().getMessage("actionCreate",
    38                         mapping.getPath()), e);
    39 
    40                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
    41                     getInternal().getMessage("actionCreate", mapping.getPath()));
    42 
    43                 return (null);
    44             }
    45             
    46             // 把新创建好的对象放到缓存中。
    47             actions.put(className, instance);
    48 
    49             if (instance.getServlet() == null) {
    50                 instance.setServlet(this.servlet);
    51             }
    52         }
    53 
    54         return (instance);
    55     }

    从代码中我们可以看出,struts1使用了一个actions的缓存来管理所有的action实例对象,当请求一个action对象时,先到actions里面查找对应的action对象,如果存在,则直接返回此对象,如果不存在,则新创建一个action对象,然后加到缓存中,再返回新创建的action实例对象。

    ②,struts2和struts1不同,struts2会为每个请求都创建一个action对象实例,所以不存在线程安全的问题。

    还是看源码:

    StrutsPrepareAndExecuteFilter类的doFilter方法:

     1     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
     2 
     3         HttpServletRequest request = (HttpServletRequest) req;
     4         HttpServletResponse response = (HttpServletResponse) res;
     5 
     6         try {
     7             prepare.setEncodingAndLocale(request, response);
     8             prepare.createActionContext(request, response);
     9             // 把dispatcher绑定到当前线程上,作为当前线程的局部变量。
    10             prepare.assignDispatcherToThread();
    11             if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
    12                 chain.doFilter(request, response);
    13             } else {
    14                 request = prepare.wrapRequest(request);
    15                 ActionMapping mapping = prepare.findActionMapping(request, response, true);
    16                 if (mapping == null) {
    17                     boolean handled = execute.executeStaticResourceRequest(request, response);
    18                     if (!handled) {
    19                         chain.doFilter(request, response);
    20                     }
    21                 } else {
    22                     execute.executeAction(request, response, mapping);
    23                 }
    24             }
    25         } finally {
    26             // 此处清楚线程局部变量。
    27             prepare.cleanupRequest(request);
    28         }
    29     }

    从上面的代码中可以看出,struts2把dispatcher作为局部变量绑定到了线程上,而Dispatcher是struts2的核心分发器,所有的action初始化操作都是在它控制之下,所以struts2是线程安全的。

  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/huashui/p/3220718.html
Copyright © 2011-2022 走看看