2012-02-09 81 views
2

我有如下的策略模式實現:靜態實例線程安全

​​

忽略返回輸入參數的不好的做法,是靜態實例實例中使用線程安全的?

+3

順便說一句:添加一個私有構造函數,以便您知道沒有人正在創建ConcreteStrategy的另一個實例(如果這是想要的行爲:) – helios 2012-02-09 14:01:35

+0

並且讓您在課程中使用「final」類。 – 2012-02-09 15:58:42

回答

2

假設ConcreteStrategy沒有修改,或者只是以線程安全的方式修改,那麼是的。 final修改器將確保(在Java 1.5+中)所有線程都至少在初始化類時所處的狀態下看到INSTANCE對象。對對象的任何後續更改都需要以通常方式(通過volatile,同步,提供線程安全的類等)進行線程安全。

+0

糾正我,如果我錯了:當我調用函數對象引用副本傳遞給方法,所以每次方法執行不同的對象。 該類用於webapp中,這些調用只共享代碼? – landal79 2012-02-09 13:53:49

+1

@ landal79:Java傳遞引用的副本。所以「aClass」參數是參考文獻的副本。但是正在使用和返回的AClass對象是相同的。把它想成指針。你可以傳遞指針,指針副本等等,但是指向的對象是一樣的。如果有一個'new',則有一個對象。 – helios 2012-02-09 14:00:33

+0

新JMM的「最終字段語義」在這裏是無關緊要的。一旦靜態初始化程序完成其工作,所有線程都會看到一個完全初始化的'ConcreteStrategy'類,只要它不做一些非常愚蠢的事情。 – 2012-02-09 15:58:12

1

通常,任何不可變或無狀態的java對象都是線程安全的。

你的例子是差不多線程安全。

參考到INSTANCE是線程安全的,因爲它是最終的。但是ConcreteStrategy的內容可能不是線程安全的(我們看不到代碼,因此無法說明)。

如果您向ConcreteStrategy對象提供適當的同步,那麼它可能是一個非常好的線程安全對象。

乾杯,尤金。

+0

假設'execute()'方法只對參數 – landal79 2012-02-09 14:05:27

+0

@ landal79執行我不明白你的意思是隻執行一個參數。你能稍微詳細些嗎? – Eugene 2012-02-09 14:06:46

+0

'execute()'方法對'aClass'實例字段值做一些評估,而ConcreteStrategy類沒有內部狀態只是一個算法。 – landal79 2012-02-09 14:16:36