2017-11-16 8 views
1

このコードは大丈夫ですか、別のロックオブジェクトを作成する必要がありますか?デッドロックなどの可能性があるかどうかを尋ねています。私は言語が許すので、それがうまくいくはずだと思うが、それがどのように機能し、なぜそれがうまくいくのか、なぜそれが問題ではないのかをむしろ理解するだろうと確信している。ロックとして同期しているオブジェクトを使用できますか

var foo = false 

fun bar() 
{ 
    synchronized(foo) { 
     foo = !foo 
    } 
} 
+0

どのように意見に基づいていますか?受け入れられた答えは意見ではなく、なぜロックと同じオブジェクトを持つことが危険なのかを説明します。 – rozina

答えて

3

コードが予期しないように壊れています。ここではJavaへの逆コンパイル、それが生成するバイトコードの簡易版は、です:

private static boolean foo; 

public static final void bar() { 
    Boolean var0 = Boolean.valueOf(foo); 
    synchronized(var0) { 
     foo = !foo; 
    } 
} 

だから、基本的にどんなオブジェクトに私のJREにBooleanクラス内部TRUEまたはFALSEシングルトンのいずれかであるvalueOf機能リターンを、ロックしています(これも簡略化されている):

public class Boolean { 
    public static final Boolean TRUE = new Boolean(true); 
    public static final Boolean FALSE = new Boolean(false); 

    public static Boolean valueOf(boolean var0) { 
     return var0 ? TRUE : FALSE; 
    } 
} 

特定、ランタイムに依存しないコードのための最善の策は、上の同期するためにAnyの別のインスタンスを作成することが考えられます。

+0

これは私が探していた情報です。すべてのインダイレクションを使用すると、すばやく隠され、同期バグは通常デバッグが困難です。情報をありがとう! – rozina

+0

これは私のロックがプリミティブ型なので起こりますか?ノンプリミティブ型であれば、この種のロックは問題ありませんか? – rozina

+1

それはボクシングから来るこの特定の問題を解決するだろう、はい。ただし、同期ブロック内で再割り当てする場合は、[Javaで非最終フィールドで同期する]と同じ考慮事項が適用されます(https://stackoverflow.com/a/6910838/4465208) 。私はまだ別の同期オブジェクトと一緒に行くだろう。 – zsmb13

関連する問題