2010-11-19 57 views
5

我看到這一點:這樣好嗎?同步(線程),那麼線程= NULL在同步塊

// thread is a member of this class 

synchronized(this.thread) 
{ 
    this.thread.running = false; 
    this.thread.notifyAll(); // Wake up anything that was .waiting() on 
    // the thread 
    this.thread = null; // kill this thread reference. 
    // can you do that in a synchronized block? 
} 

它是確定設置thread=null,同時仍保持對鎖嗎?

我發現這個塊有點BB代碼。

+1

是否有任何理由你沒有使用Thread.interrupt(),因爲這是由底層庫支持的? – 2010-11-19 17:51:26

回答

7

是的,沒關係。 synchronized語句將獲取它所鎖定的引用的副本,並使用該副本來計算最終解鎖的內容。

Java語言規範的Section 14.19是不是這實際上明確的,但它確實狀態的表達在開始評估 - 並沒有提及以後再評價它。

+0

這很好,但是將線程引用設置爲null是個不錯的主意。 – Adamski 2010-11-19 16:08:41

+1

@Adamski:我傾向於採取一個相當強烈的觀點,我首先要實現同步 - 我認爲我會避免進入:) – 2010-11-19 16:10:31

+0

同意 - 事實上IntelliJ在這種情況下警告我關於同步一個非最終變量。 – Adamski 2010-11-21 22:15:44

3

有一個區別:

synchronized(this.thread) 

您在對象場同步this.thread

this.thread = null; 

您重新分配的領域。你對上面引用的對象沒有做任何事情,所以鎖仍然有效。

0

你可以做到這一點,但幾乎可以肯定的是,無論它試圖達到什麼目的,代碼都是錯誤的。發佈整個代碼,我保證它顯然是程序員不理解併發性。

請勿重新分配用於同步的變量。

0

如果您還有一個向線程分配新值的塊,則只會出現問題。在這種情況下,你有一個競爭條件,因爲兩個塊不鎖定在同一個對象上,但會更新同一個字段,並且它將隨機選擇哪個塊最後分配值。

1

同步表達式在入口時被取消引用,因此該鎖的任何後續用戶都將得到NullPointerException。您可以通過在同步塊之前放置空檢查來解決該問題,但是隨後您已經引入了競爭條件。

+0

「評估」入境。 – EJP 2010-11-19 23:55:05

+3

@EJP多於評估 - 評估爲null的表達式不會導致NullPointerException。 – 2010-11-20 07:52:16