このコードで IllegalMonitorStateException が発生する原因は何ですか
synchronized(syncCount){
syncCount--;
syncCount.notify();
}
私が知る限り、実行中のスレッドには通知が呼び出されたオブジェクトのモニターが必要なので、私は少し混乱しています。私のコードは間違っていないように見えますが、どういうわけかそうです。
このコードで IllegalMonitorStateException が発生する原因は何ですか
synchronized(syncCount){
syncCount--;
syncCount.notify();
}
私が知る限り、実行中のスレッドには通知が呼び出されたオブジェクトのモニターが必要なので、私は少し混乱しています。私のコードは間違っていないように見えますが、どういうわけかそうです。
タイプInteger
または類似の?--
不変Integer
オブジェクトを別のものに置き換えます。したがってnotify
、 とは異なるオブジェクトを呼び出していますsynchronized
。
あなたのコードは次のものと同等です:
Integer syncConunt = Integer.valueOf(5);
[...]
synchronized (syncCount) {
syncCount = Integer.valueOf(syncCount.intValue() + 1);
syncCount.notify();
}
あなた一人じゃありません。J2SE 5.0 の前でさえ、同期ブロック内で参照を割り当てたサンプル コードが本に掲載されているのを見たことがあります。一般に、ロック フィールドをマークすることをお勧めしますfinal
。
もう 1 つの重要な点は、コードが「所有」していないオブジェクトで同期することです。Integer
オブジェクトは共有されます ( Integer.valueOf(int)
-128 から 127 の間、またはそれ以上の値で呼び出された場合、まったく同じインスタンスが返されます)。これが 2 つの無関係なコードによって行われた場合、隠れた相互作用が発生します。これは、関連のないコード間でインスタンスが共有されるすべての型に適用されます。一般的な例はInteger
、String
、Class
(静的な同期メソッドで使用される) およびThread
(Sun の実装では、Thread
たまたま のロックとして使用されるjoin
) です。