我有一个使用一些全局变量的jsp应用程序(使用Spring)。但是,我需要多个人同时使用这个程序。什么是使其成为线程安全的最佳方法,使程序的每个实例独立于其他实例?
::编辑::如果我不使用任何单件对象,我还好吗?
答案 0 :(得分:3)
每个请求都在自己的线程中处理。这些线程由servlet容器管理。在servlet中使用静态全局变量不是一个好主意。所有实例变量对所有线程都是通用的,因此可能导致模糊状态。
我建议将此类型信息保存在范围变量(应用程序,会话,请求,页面等)中。
如果必须使用全局变量,则需要同步对其的访问以避免未知状态。
答案 1 :(得分:2)
典型的容器使用每个请求的线程模型,因此您可以直接构建一个容易识别的边界。一般规则是永远不会将任何状态存储在多个请求(线程)可见的任何对象中,除非国家实际上是不可改变的。例如,像这样的单例控制器
@Controller
@RequestMapping("/schedule")
class MyController {
private Scheduler scheduler;
@RequestMapping(method = RequestMethod.POST)
public void scheduleSomething(Foo foo) {
scheduler.schedule(foo);
}
}
是有状态的 - 调度字段保持状态 - 但状态在启动时初始化并在所有请求/线程中保持不变。另一方面,如果你有这样的单例控制器:
@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将以非线程安全的方式不断变化。在整个应用程序中遵循这一推理方式,您将是安全的。