2011-08-23 68 views
1

我有一个使用了几个全局变量的jsp应用程序(使用Spring)。但是,我需要多个人才能够同时使用此程序。什么是使线程安全的最佳方式,以便程序的每个实例都独立于其他实例?如何让jsp的弹簧应用程序线程安全?

::编辑::我是没关系,如果我不使用任何单一对象?

+2

单身是完全确定的,如果他们没有可变状态。 Spring bean默认情况下是singleton,但传统多层应用程序中的大部分Spring bean都没有状态。 –

回答

3

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

我建议保存在一个范围变量此类型的信息(应用,会话,请求,页等)。

如果必须使用全局变量,那么你将需要访问它同步,以避免未知状态。

+0

那么基本上没有单身人士的对象? – Steve

+2

@Steve - 你的问题是关于全局(和/或静态)变量。我希望你不要将它们与[singletons]混合(http://en.wikipedia.org/wiki/Singleton_pattern)。要回答你的评论,你可以使用singleton,只要它们保存在'ServletContext'中即可。 – CoolBeans

+0

啊,我以为他们本质上是一样的。谢谢。 – Steve

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将在非thread-不断变化安全的方式。通过你的整个应用程序遵循这一推理,你会很安全。

+0

+1:很好的例子:) – CoolBeans