2011-10-04 32 views
3

我在某處讀到啓動線程對發生關係之前有一些特殊效果。現在我不確定我的代碼是否保證關係之前發生的事情,所以請賜教。Java在線程啓動之前發生的事

我有一個Dispatcher線程和一個Worker類實現Runnable接口。分派器線程創建Worker的新實例,並通過帶有元素的add方法在Worker實例中填充LinkedList

然後分派器通過execute方法將Worker實例傳遞給ExecutorService

然後Worker類中的run方法開始訪問並從LinkedList中刪除東西。

工作人員的新開始實例是否與調度員留下的LinkedList相同的狀態?或者可能是LinkedList處於不穩定狀態?我需要用同步方法填寫LinkedList嗎?

回答

2

Java語言規範writes

啓動一個線程的動作同步,與在它啓動線程的第一個動作。

如果操作x同步,與接下來的動作y,那麼我們也有hb(x, y)

如果我們有兩個動作xy,我們寫hb(x, y)表明,x之前發生y

不過,從你的描述,目前尚不清楚這是否是你的情況相關的,因爲你談論的執行者,而是創建了遺囑執行人或它的工作線程啓動時不會解釋。

什麼是相關的是從Executor's JavaDoc以下exerpt:

內存一致性效果:之前 操作在一個線程中提交Runnable對象的Executor 發生,之前其開始執行,也許在另一個線程。

因此,只要分派器線程在提交Runnable後不再訪問列表,您的代碼就是安全的。

1

如果使用鎖定或其他同步原語,並且您只是使用普通的舊ArrayList,則這兩個線程可能會看到不同的狀態。

在兩個獨立線程之間協調工作時,您必須使用線程安全/併發數據結構或使用同步代碼來保證線程之間存在一致的「內存快照」。

這一點很重要的原因之一是由於緩存。這兩個線程在不同的處理器上併發執行,可能會在一些本地寄存器(這些處理器是本地的)中緩存一些對象。

+0

謝謝,我雖然如此。但調度員不得再次觸摸數據。是否足以通過構造函數Worker(LinkedList blahBlah)傳遞新創建的LinkedList。構造函數在關係之前發生,不是嗎? –

+0

@Franz - 爲什麼不讓工作線程創建列表,如果所有的調度程序都這樣做,就是構建它們?我不完全確定構造函數是否會在關係之前發生。原則上你可能是對的。 – ripper234

+0

該死的,我很擅長這個東西,如果沒有使用,知識如何快速生鏽,真是太棒了。 – ripper234

4

根據本細則:ExecuterService javadocs

內存一致性效果:操作在一個線程之前提交一個Runnable或贖回任務的一個ExecutorService的發生,之前該任務所採取的任何行動,反過來這發生 - 在通過Future.get()檢索結果之前。

這意味着你的概念是正確的。

相關問題