2013-05-15 31 views
3

說我有一個線程T1。我在該線程中創建了一個對象,例如Dog和設置一些屬性(namecolor)等MultipleThreads和同步線程可見性

然後我線程另一個線程T2(從T1)和Dog對象傳遞給它。在此之後,T1不會更改對象的任何屬性,甚至不想讀取它,但會保留到實際參考(Dog d)。

問:

  1. 假設T2不Dog改變什麼,狗是線程安全的(從知名度待機點將T2總是看到由T1設置相同的名稱和顏色。)?
+0

兩個線程都不改變Dog實例,它絕對是線程安全的 – hoaz

+0

僅僅因爲你選擇不改變對象並不意味着它是線程安全的。使用這個邏輯,* everything *將是線程安全的。您似乎在談論Java的線程緩存而不是線程的可見性*安全* –

回答

1

Dog是線程安全只有當值只是實例變量震盪。

如果它們不是不穩定的,T2有可能讀取陳舊的數據。

+4

在OP示例中不需要volatile。 – assylias

+0

你能詳細說明一下嗎?如果您沒有將該變量標記爲volatile,則不同的線程總是會導致讀取緩存而不是讀取正確的值。 –

+1

如果你有這個序列:[在T1]:'dog.setName(「doggy」); T2.start();'和[在T2]'println(dog.getName());' - 你有保證在T2中打印'doggy'或者可能有更近期的值。這是因爲't2.start()'作爲內存屏障,阻止T2讀取較舊的值。 – assylias

-1

「狗線程安全嗎?」如果它不是一成不變的,那麼我會說不。

「從知名度的角度來看,T2總是會看到與T1所設定的名稱和顏色相同的顏色嗎?」大概。 (注意,如果事情不揮發或同步。

簡單處理這個辦法是在其上同步。這將使它的tHead安全。

+0

可變性不排除線程安全。如果你有易變的變量,它們是線程安全的,因爲你將無法讀取陳舊的數據。如果值是不可變的,並且您對它們進行計算,那麼保證線程安全性就更簡單了。 –

+0

這就是爲什麼我說「可能」,但沒有任何信息給狗的內部細節。我不想推測。 – Nick

+0

OP明確表示Dog(及其屬性)在創建線程T2後沒有更改。因此,對於這種特殊情況,Dog在創建T2之後變得不可變(不是真正意義上的),因此線程安全。 – Parvez

2

在一個線程中的每個動作可以看出,線程之前不管發生什麼事情開始在你的榜樣,T2是保證看到T1進行的所有更改t2.start()被稱爲前。

這不會讓Dog線程安全的,但你的這個類的使用是線程安全的。

然而要注意之後由T1或T2進行的任何後續更改點不能保證從其他線程可見。


參考:JLS #17.4.5

調用開始()上線之前發生在啓動線程的任何行動。

0

只要:

  • 您的實現擔保由多個線程同時訪問您Dog d對象的屬性

  • Dog d時是免費的競態條件「 s屬性的訪問受到保護,免受競爭條件的影響

...你可以認爲它是線程安全的。

我現在說現在不可能說你的解決方案是否是線程安全的。因爲沒有提及數據訪問原理或鎖。

我懷疑它不是線程安全的!