デッドロックに関連するモック・バンク・データベースの問題です。私はすでに私が答えだと思っているものを持っていますが、これが良い解決策であれば私は不思議です。質問は以下の通りです提起:あなたは、次のコードでデッドロックを防ぐんモック・バンキング・データベースでのデッドロックの防止
どのように?:
void transaction(Account from, Account to, double amount)
{
Semaphore lock1, lock2;
lock1 = getLock(from);
lock2 = getLock(to);
wait(lock1);
wait(lock2);
withdraw(from, amount);
deposit(to, amount);
signal(lock2);
signal(lock1);
}
これがデッドロックになることができる方法は、二つのスレッド経由でトランザクションを呼び出し()メソッド(またはプロセス?)対価口座と同時に、すなわち:
トランザクション(節約、チェック、1);スレッド1および
トランザクション(確認、節約、2);
私の理解が乏しいことから、何が起こっているのか、なぜデッドロックが発生しているのかは、両方のスレッドがロックを取得しようとしているためロック順序が守られていないためです。
私の迅速かつ汚いソリューションは、(機能トランザクションの外側でロックを移動させることであろう)と呼ばれるとき、それは次のようになりどこへ:
//somewhere in main
Semaphore lock1, lock2;
lock1 = getLock(from);
lock2 = getLock(to);
wait(lock1);
wait(lock2);
transaction(checking, savings, 2);
signal(lock2);
signal(lock1);
//.....
をトランザクションと、このように見える:
void transaction(Account from, Account to, double amount)
{
withdraw(from, amount);
deposit(to, amount);
}
トランザクションは技術的に重要なセクションなので、これらのトランザクションを同時に実行することはできません。これがJavaプログラムであれば、関数宣言にvoidの後にsynchronizedという単語を入れてモニターを使うこともできますか?それは働くだろうか?それはそれを行うよりスマートな方法のようです。
また、私はこのことについて全く理解していないかもしれないので、私の説明が正確でない場合は、特に学校を教えてください。ありがとう。二つのセクションに、このクリティカルセクションの分離
+1これは簡単で正確な解決方法です。 – usr
私はそれが与えられていないので、解決策を決定するためにそのコンテキストでアカウントIDを使用して教授が私と大丈夫だろうかどうか私はそれには同意するでしょう。現実の世界では、なぜこれが完全にはうまくいかないのか分かりません。 – montag
明らかに、 'Account' @montagで比較できる他の独自のフィールドを使うことができます。しかし、私は質問の要件を理解しています。トランザクション内でロックを移動することも別の解決策です。 – Gray