Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么struts操作类不是线程安全的?_Java_Struts2_Struts - Fatal编程技术网

Java 为什么struts操作类不是线程安全的?

Java 为什么struts操作类不是线程安全的?,java,struts2,struts,Java,Struts2,Struts,我可以在许多网站上看到Struts操作类不是线程安全的。我不明白为什么会这样 我还读了一本书,书中说,Struts操作类被缓存和重用以提高性能 以线程安全方式实现操作类为代价进行优化“ 缓存操作类和线程安全有什么关系 如果缓存并重用任何类,则存在多线程并发访问被破坏的风险。在web应用程序中,每个请求都在一个线程上处理。假设您有10个操作实例,但您的容器正在处理20个请求——在本例中,您的10个操作都被重用,因为您处理的请求比可用于服务它们的操作多 线程安全问题只有在动作中存在重用状态时才会出现

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

我还读了一本书,书中说,Struts操作类被缓存和重用以提高性能 以线程安全方式实现操作类为代价进行优化“


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

如果缓存并重用任何类,则存在多线程并发访问被破坏的风险。在web应用程序中,每个请求都在一个线程上处理。假设您有10个操作实例,但您的容器正在处理20个请求——在本例中,您的10个操作都被重用,因为您处理的请求比可用于服务它们的操作多

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

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

为什么不为每个请求创建一个新的“操作”对象?到底是什么

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

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

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

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

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

查看实际的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”
来解决这种情况下的线程安全问题

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


也许这会有帮助

你在哪里读到这本书的?这本书是2007年3月31日出版的。Struts2于2008年发布。见:。。。无论如何,S2是一个与S1非常不同的产品。。。说这句话是为了确保您了解S1和S2仅通过名称相关。我添加了
struts
标记,因为这已经成为比较版本1和版本2之间动作类实例差异的一种方式。Struts2并不老。这里有一个很好的比较表:我认为unjutable指的是Struts1,它很旧。同意Struts 2并不老,当然!我只是写了上面的评论,这样新程序员就不会对Struts产生错误的印象。当我们今天说“Struts”时,大多数时候我们指的是Struts2……因为Struts对Struts2的声誉有多坏,所以在写作时我试着说“Struts2”,然后在将来的所有引用中使用S2。他们的命名选择是多么痛苦啊!是的,我同意。我希望它仍然被称为网络工作。不管我们怎么称呼它,它都是一个很棒的框架。你能用一个很好的工作示例来解释struts 1和struts 2的区别吗?我们如何配置堆栈以始终使用新操作?在struts 1中可以这样做吗?