2010-11-19 21 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()を使用していない理由はありますか?これは、基礎となるライブラリでサポートされていますか? –

答えて

7

はい、問題ありません。 synchronizedステートメントは、ロックしている参照のコピーを取り、そのコピーを使用して最後にロックを解除するものを解決します。 Java言語仕様の

Section 14.19これについて実際に明確ではないが、それはは、式が開始時に評価されていることを状態を行い - そして後で再びそれを評価する言及していません。

+0

これは問題ありませんが、スレッド参照をnullに設定するのは良い考えです。 – Adamski

+1

@Adamski:正直言って私が最初に同期したことについて合理的に強い見方をする傾向がある - 私はそれに入るのを避けると思った: –

+0

合意 - 実際にIntelliJはこの状況で、非最終変数。 – Adamski

3

違いがあります:

synchronized(this.thread) 

あなたはあなたがフィールドに再割り当てされている

this.thread = null; 

へのオブジェクトのフィールドthis.threadポイントを同期しています。上で参照したオブジェクトで何もしていないので、ロックはまだ有効です。

0

これは可能ですが、達成しようとしているコードが間違っていることはほとんど間違いありません。コード全体を投稿すると、プログラマが並行性を理解していないことは明らかです。

同期に使用する変数を再割り当てしないでください。

0

スレッドに新しい値を割り当てるブロックがある場合にのみ問題が発生します。その場合、2つのブロックが同じオブジェクトでロックされず、同じフィールドが更新され、最後に値を割り当てるブロックがランダムになるため、競合状態が発生します。

1

同期式は入力時に参照解除されるため、このロックのそれ以降のユーザーはNullPointerExceptionを取得します。同期ブロックの前にヌルチェックを置くことで回避できますが、競合状態を導入しました。

+0

エントリー時に '評価中'。 – EJP

+3

@EJP以上評価されました - nullに評価される式はNullPointerExceptionを引き起こしません。 –