繁体   English   中英

为什么 struts Action 类不是线程安全的?

[英]why are struts Action classes not thread safe?

我可以在许多网站上看到 Struts Action 类不是线程安全的。 我不明白为什么会这样。

我还读了一本书,上面写着“Struts 动作类被缓存并重用以进行性能优化,代价是必须以线程安全的方式实现动作类”

缓存操作类和线程安全有什么关系? .

缓存操作类和线程安全有什么关系?

如果您缓存和重用类的实例,允许多个线程同时访问同一个实例,则该类本质上不是线程安全的*。 如果在类上放置可变实例或静态字段,并发下的结果将是出乎意料的和有问题的。 另一方面,如果每个线程都有自己的类实例,则该类本质上是线程安全的。

  • Struts 1 动作类不是线程安全的。 您不应在类上放置任何可变字段,而应为传递给操作的表单字段使用 Form Bean 类。
  • Struts 2 动作类是线程安全的。 为每个请求实例化新副本,并将实例字段放在类上是框架中的核心概念。

* 如果实例或静态字段是不可变的,那么多个线程可以同时访问它。

如果任何类被缓存和重用,多线程并发访问就有损坏的风险。 在 Web 应用程序中,每个请求都在一个线程上处理。 假设您有 10 个操作实例,但您的容器正在处理 20 个请求——在这种情况下,您的 10 个操作每个都被重用,因为您有更多的请求正在执行,而不是可用于为它们提供服务的操作。

只有在操作中重用某些状态时,线程安全问题才会浮出水面。 如果是这种情况,那么为一个请求提供服务的操作可能会在共享变量中设置一个值,但是另一个线程可能会接管,并且该操作可能会再次修改共享变量。 在这种情况下,当原始线程接管时,共享状态已被修改。

解决这个问题的简单方法是将堆栈配置为始终使用新操作,或者确保您的操作中没有共享状态。

为什么不为每个请求创建一个新的“动作”对象? 什么世界??

因为 Struts 太老了,他认为每个请求周期多创建一个对象就像花一美元买一杯咖啡一样昂贵。 (也就是说,很贵。因为他真的老了。)

查看实际的 struts 源代码,您会看到它只是返回实例化的操作类。 依此类推,两个请求可以命中同一个实例变量,如果没有正确同步就会产生很多问题。

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();

    Action instance;

    synchronized (actions) {
        // Return any existing Action instance of this class
        instance = (Action) actions.get(className);

        if (instance != null) {
            return (instance);
        }
   .......
    }
.....
}

在为一个旧的 Struts 1 项目寻找此问题的解决方案时,该项目由于对同一操作的某些 ajax 调用而随机行为,我认为您可以通过在您的struts-config.xml上使用scope="request"来解决这种情况下的线程安全问题struts-config.xml文件。

<action path="/blabla" type="blabla" name="bla" scope="request">

也许这有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM