2011-04-13 66 views
2

爲什麼struts action類是單例?struts action singleton

其實我得到的觀點是它是多線程的。但在千次請求觸及同一動作的時候,我們爲了防止線程問題而同步放置,那麼它不會給予bcoz線程處於等待狀態的良好性能,並且程序需要時間。

是否有任何方式從行動類中刪除單身人士?

更多信息請訪問:http://rameshsengani.in

回答

20

你在問爲什麼Action類是單例,但我認爲你也有一些理解線程安全的問題,所以我會試着解釋兩者。

首先,Struts Action類沒有作爲單例實現,框架只使用它的一個實例。但是因爲只有一個實例用於處理所有傳入的請求,所以必須注意不要在Action類中執行任何與線程安全無關的操作。但事情是:默認情況下,,Struts Action類不是線程安全的

Thread safety意味着一段代碼或對象可以安全地在多線程環境中使用。一個Action類可以在多線程環境中安全地使用,並且您可以同時在一千個線程中使用它,而且沒有問題...如果您正確實現它,則爲

Action class JavaDoc

動作必須以線程安全的方式進行編程,因爲控制器將共享相同的實例多個同時請求。這意味着你應該考慮到以下幾點:

  • 實例和靜態變量不能用於存儲與特定請求的狀態有關的信息。它們可能被用於跨同一行動的請求共享全球資源。

  • 訪問其他資源(JavaBeans,會話變量等)必須同步,如果這些資源需要保護。 (但是,總的來說,資源類應該通過推導,並建立自己的設計來提供自己的保障,以便在必要的。

你使用Struts的Action。當你這樣做,你要照顧遵守上述規則這意味着這樣的事情是NO-NO:。

public class MyAction extends Action { 
    private Object someInstanceField; 
    public ActionForward execute(...) { 
     // modify someInstanceField here without proper synchronization ->> BAD 
    } 
} 

,除非你做錯了什麼他們喜歡在上面的代碼中你不需要Action類同步的是,執行到您的行動的切入點是execute方法。

該方法接收所有需要的參數。您可以在execute方法中同時執行1000個線程,因爲每個線程都有自己的執行堆棧用於方法調用,但不適用於堆中的數據(如someInstanceField),它在所有線程。

修改someInstanceField時沒有正確同步,所有線程都會按照他們的要求進行操作。

所以是的,Struts 1 Action類並不是線程安全的,但是這意味着你不能安全地在其中存儲狀態(即使它們成爲statefulf),或者你必須正確同步它。

但是,如果你保持你的Action類實現無狀態,那麼你就沒問題,不需要同步,線程也不會彼此等待。

爲什麼struts action類是單例?

這是設計。再次的JavaDoc解釋它:

一個行動是一個傳入的HTTP請求的內容,並應被執行以處理此請求

請求參數被綁定到相應的業務邏輯之間的適配器Web層,並且您不希望將這種類型的數據發送到您的業務邏輯類中,因爲這會在兩個層之間創建緊密耦合 ,這將導致無法輕鬆地重用您的業務層。因爲將Web對象轉換爲模型對象(我不是說ActionForm bean在這裏)應該是Action類的主要目的,所以它們不需要維護任何狀態(並且不應該),而且,沒有理由有更多的這些傢伙的實例,都做同樣的事情。只有一個會做。

如果您希望通過將信息持久保存到數據庫中,您可以在模型中安全地維護狀態,或者您可以使用http會話維護Web狀態。在Action類中維護狀態是錯誤的,因爲這引入瞭如上所述的同步化的需要。

有沒有辦法從操作類中刪除單例?

我想你可以擴展Struts和覆蓋的RequestProcessor.processActionCreate默認行爲,以自己創建的每個請求 的行動,但是這意味着在struts之上添加另一層改變其「正常」的行爲。我已經看到這樣的東西在一些應用程序中變壞,所以我不會推薦它。

我的建議是讓你的Action類保持無狀態,併爲其創建單個實例。

如果你的應用程序是新的,你絕對需要statefull動作,我想你可以去的Struts 2(他們改變了設計,並且Action實例現在每個請求一個)。 But Struts 2 is very different from Struts 1所以,如果你的應用程序是舊的,它可能很難遷移到Struts 2.

希望這現在說清楚。

相關問題