Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.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 如何使jsp spring应用程序线程安全?_Java_Spring_Jsp_Concurrency_Thread Safety - Fatal编程技术网

Java 如何使jsp spring应用程序线程安全?

Java 如何使jsp spring应用程序线程安全?,java,spring,jsp,concurrency,thread-safety,Java,Spring,Jsp,Concurrency,Thread Safety,我有一个jsp应用程序(使用Spring),它使用了几个全局变量。然而,我需要多人同时使用这个程序。使程序的每个实例都独立于其他实例的线程安全的最佳方法是什么 ::编辑::如果不使用任何单例对象,我可以吗?每个请求都在自己的线程中处理。这些线程由servlet容器管理。在servlet中使用静态全局变量不是一个好主意。所有实例变量对于所有线程都是公共的,因此它可能导致不明确的状态 我建议将此类型信息保存在范围变量(应用程序、会话、请求、页面等)中 如果必须使用全局变量,则需要同步对该变量的访问以

我有一个jsp应用程序(使用Spring),它使用了几个全局变量。然而,我需要多人同时使用这个程序。使程序的每个实例都独立于其他实例的线程安全的最佳方法是什么


::编辑::如果不使用任何单例对象,我可以吗?

每个请求都在自己的线程中处理。这些线程由servlet容器管理。在servlet中使用静态全局变量不是一个好主意。所有实例变量对于所有线程都是公共的,因此它可能导致不明确的状态

我建议将此类型信息保存在范围变量(应用程序、会话、请求、页面等)中


如果必须使用全局变量,则需要同步对该变量的访问以避免未知状态。

每个请求都在其自己的线程中处理。这些线程由servlet容器管理。在servlet中使用静态全局变量不是一个好主意。所有实例变量对于所有线程都是公共的,因此它可能导致不明确的状态

我建议将此类型信息保存在范围变量(应用程序、会话、请求、页面等)中


如果必须使用全局变量,则需要同步对该变量的访问以避免未知状态。

典型的容器使用每个请求一个线程的模型,因此您有一个易于识别的内置边界。一般规则是永远不要在对多个请求(线程)可见的任何对象中存储任何状态,除非该状态实际上是不可变的。例如,像这样的单例控制器

@Controller
@RequestMapping("/schedule")
class MyController {
    private Scheduler scheduler;

    @RequestMapping(method = RequestMethod.POST)
    public void scheduleSomething(Foo foo) {
        scheduler.schedule(foo);
    }
}
是有状态的——schedular字段保存状态——但状态在启动时初始化,并且在所有请求/线程中保持不变。另一方面,如果您有这样的单例控制器:

@Controller
@RequestMapping("/schedule")
class MyController {
    private Scheduler scheduler;
    private Foo foo;

    @RequestMapping(method = RequestMethod.POST)
    public void scheduleSomething(Foo foo) {
        this.foo = foo;
        scheduler.schedule(this.foo);
    }
}

对于并发访问来说,这是绝对不安全的,因为所有请求都会转到同一个控制器,并且foo将以非线程安全的方式不断变化。在整个应用程序中遵循这条推理路线,您将是安全的。

一个典型的容器使用每请求一个线程的模型,因此您有一个易于识别的内置边界。一般规则是永远不要在对多个请求(线程)可见的任何对象中存储任何状态,除非该状态实际上是不可变的。例如,像这样的单例控制器

@Controller
@RequestMapping("/schedule")
class MyController {
    private Scheduler scheduler;

    @RequestMapping(method = RequestMethod.POST)
    public void scheduleSomething(Foo foo) {
        scheduler.schedule(foo);
    }
}
是有状态的——schedular字段保存状态——但状态在启动时初始化,并且在所有请求/线程中保持不变。另一方面,如果您有这样的单例控制器:

@Controller
@RequestMapping("/schedule")
class MyController {
    private Scheduler scheduler;
    private Foo foo;

    @RequestMapping(method = RequestMethod.POST)
    public void scheduleSomething(Foo foo) {
        this.foo = foo;
        scheduler.schedule(this.foo);
    }
}

对于并发访问来说,这是绝对不安全的,因为所有请求都会转到同一个控制器,并且foo将以非线程安全的方式不断变化。在整个应用程序中遵循这条推理路线,您将是安全的。

所以基本上没有单例对象?@Steve-您的问题是关于全局(和/或静态)变量的。我希望你没有把它们混在一起。要回答您的评论,您可以使用singleton,只要它们保存在
ServletContext
中即可。啊,我认为它们基本上是一样的。谢谢。@Steve-不,它们不一样。最重要的是,singleton是一种设计模式。谷歌“singleton模式java”来更好地理解它。详细回答这个问题超出了我的范围。如果这些单例请求是独立的和不变的,那么单例就可以了。他的建议是把信息放在适当的范围内。特定于用户但不是请求的数据放入会话范围。特定于请求的数据,放入请求范围等。在单例对象中,任何全局的、不能更改的数据都可以。这就是它们的用途。所以基本上没有单例对象?@Steve-你的问题是关于全局(和/或静态)变量的。我希望你没有把它们混在一起。要回答您的评论,您可以使用singleton,只要它们保存在
ServletContext
中即可。啊,我认为它们基本上是一样的。谢谢。@Steve-不,它们不一样。最重要的是,singleton是一种设计模式。谷歌“singleton模式java”来更好地理解它。详细回答这个问题超出了我的范围。如果这些单例请求是独立的和不变的,那么单例就可以了。他的建议是把信息放在适当的范围内。特定于用户但不是请求的数据放入会话范围。特定于请求的数据,放入请求范围等。在单例对象中,任何全局的、不能更改的数据都可以。这就是它们的目的。如果它们没有可变状态,那么单例就完全可以了。默认情况下,SpringBean是单例的,但是传统多层应用程序中的大多数SpringBean都没有状态。如果没有可变状态,单例就完全可以了。默认情况下,Springbean是单例的,但传统多层应用程序中的大多数Springbean都没有状态。