-
11-09-2019 - |
質問
私はスレッド セーフ プログラミングにかなり慣れていないので、以下のようなものがある場合、コンパイルして実行するとデッドロックが発生しないだろうかと疑問に思っていました。
public class Foo
{
protected CustomClass[] _mySynchedData = new CustomClass[10];
public void processData()
{
synchronized(_mySynchedData) {
// ...do stuff with synched variable here
}
}
}
public class Bar extends Foo
{
@Override
public void processData()
{
synchronized(_mySynchedData) {
// perform extended functionality on synched variable here
// ...then continue onto parent functionality while keeping synched
super.processData();
}
}
}
Bar testObj = new Bar();
// Deadlock?
testObj.processData();
解決
あなたのコードは、単一スレッドのみを表示します。
が唯一つのスレッドを使用すると、任意のデッドロックを得ることができる方法はありません。
を追加しました:
Java言語は、彼らが正式にリエントラント同期を呼んで対応しています。
それは基本的に単一のスレッドがすでに所有しているロックを再取得できることを意味します。
他のヒント
あなたの質問は、あなたが同じオブジェクトに2回を同期するときに起こることです。
答えは次のとおりです。Javaは(それがsynchronized
が動作する内部データ構造です)モニターを所有するスレッド最初にチェックします。所有者スレッドは、現在のスレッドと同じであるため、Javaは継続されます。
あなたは2台のモニタを持っていて、別のスレッドで異なる順序でそれらをロックしようとした場合、デッドロックにのみ発生する可能性があります。
Javaのsynchronizedキーワードで撮影したロックは、入れ子にサポートしています。
コードにスレッドが 1 つしか含まれていないため、デッドロックが発生しないという点では、RichN は正しいです。また、デッドロックが発生するには、複数のスレッドが取得を行う必要があることにも注意してください。 複数のロック (とはいえ、 順番が違う) デッドロックが発生します。
コードは現在 1 つのロックのみを参照しています。に関連するもの _mySynchedData
. 。Java のロックは次のとおりであるため、ロックを 2 回試行しても問題はありません。 リエントラント.