2011-08-23 104 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