2014-04-15 29 views
3

我有一個ContainerClass類,它有一些靜態變量。 幾個同時運行的線程訪問這些靜態變量,並且它們始終需要具有最新的值。Java - 當沒有實例化對象時需要static和volatile?

的線程訪問的變量沒有ContainerClass的對象,而是像

ContainerClass.variable_A; 

我還需要聲明的是在ContainerClass線程volatile之間共享的變量?任何緩存是否發生在線程中?

編輯:一些清晰的編輯。

EDIT2:爲了更清楚:多個線程閱讀這些volatile變量的值,但只有一個線程他們。讀線程會緩存變量還是始終保持最新版本,因爲讀線程中沒有對象實例化?

+1

你確定波動性足夠嗎?如果你曾經使用'ContainerClass.variable_A ++',volatile將不會使其成爲原子。 – user2357112

+0

有很好的例子答案。 http://stackoverflow.com/a/7943472/1370062 – RMachnik

回答

4

快速回答是的。 Static是一個實例/類修飾符。它與同步和內存模型無關。雖然volatile會確保1)指令優化不會將操作交換爲易失變​​量,以便在執行之前/之後執行任何操作2)在將操作volatile變量之前發生的任何事情都寫入主內存。所以是的,你需要使其變得不穩定。

說了以上所有我個人認爲你的設計不好。暴露這樣的全局靜態volatile基本上違反了封裝。除非你有這樣的性能原因(我猜不是這樣),靜態var最好是私有成員和方法返回的最新值,以更好地封裝。

+0

'static'不是一個可見性修飾符。它就是所謂的「實例/類」修飾符。 您的2)有關易失變量的聲明也是不正確的,它可以確保在讀取此值之前將某些內容寫入易失變量。 –

+0

當然需要您對靜態因素的評論,我輸入得太快。雖然我不太同意波動性。它確保將某些東西寫入其他變量 - 在爲同一線程讀取易失性值之前,而易失性只保證跨線程的最新值,但在讀寫序列中沒有保證。 –

+0

'volatile'指令不能用非易失性進行重新排序,這爲我們提供了對其中寫入的值的可見性的保證,但是隻有在** volatile讀取之後纔會發生 - 在寫入volatile變量之後(可能有點不正確的英文,對不起)。爲了達到這個保證,非易失性寫入應該發生 - 在易失性寫入之前。 –

1

您問題的確切答案是這取決於。如果這些變量改變了我想要的值,並且沒有執行額外的同步 - 那麼是的,您需要爲這些變量的值提供可見性保證,因爲static修飾符本身沒有提供有關可見性的內容。 volatile可以是你的選擇。

爲防萬一您的變量沒有改變,使他們final也足夠可見性保證。