まず、デッドロックの定義
マルチスレッドおよびマルチプロセスは、システムリソースの利用率を向上させ、システムの処理能力を向上させることができます。デッドロック-しかし、同時実行も新たな問題をもたらしています。複数のスレッドが、外力の不在は、これらのプロセスが前方に移動することはできません(互いに待ち)によって引き起こされるリソースについて競合するので、いわゆるデッドロックは、デッドロックを指します。
私たちはいくつかの例のデッドロックを説明しましょう。
人生の例を見て、しかし、二人だけの箸のペアとのお食事は、2人は(も食べて2本の箸を持っている)食べるようにターンを取ります。いくつかの時点では、男は右の箸を取った彼は左の箸を取った、2人は同時に、別のリソースを待って、この時間A仕上げをリソースを占有し、それがB、共感、またBを待って箸を占領リリース待機と死のサイクルに巻き込まので、箸の所持を食べた後、それを解放、食べ続けることはできません。。。
同様の状況は、コンピュータシステム内に存在しています。例えば、コンピュータシステムは唯一つの入力装置およびプリンタを有するプリンタの使用を要求しながら、プロセスP1は、入力装置を占めるが、この時間は、プリンタは、プロセスP2によって占有されている、及びP2は、プリンタの前に放出されませんそして使用する要求がP1の入力装置によって使用されています。だから、お互いに2つのプロセスが延々ともはや待つことを、我々は、2つのプロセスが状態をデッドロックこの時間を継続することはできません。
第二に、デッドロックの理由
競技1)システムリソース
従来のシステムは、不可分のリソースを有し、その数は、実行中の複数のプロセスのニーズを満たすには不十分であり、それは、動作中にそのようなように、テープドライブ、プリンタ、等のリソース上行き詰まりによる処理を行います。リソースのための唯一の競争、それがデッドロックを奪われないことがあり、リソースの競合が剥奪ないデッドロックにつながることができます。
2)不正順序を移動させる処理
リソースの解放正しく、操作、要求および注文時のプロセスもデッドロックにつながります。例えば、並行処理がP1、P2は、それぞれ、リソースR1、R2、およびアプリケーションプロセスP1リソースR2、プロセスP2必要なリソースがブロックされているため占有されどちらもリソースR1、申請維持します。リソースの解放正しく、操作、要求および注文時のプロセスもデッドロックにつながります。例えば、並行処理がP1、P2は、それぞれ、リソースR1、R2、およびアプリケーションプロセスP1リソースR2、プロセスP2必要なリソースがブロックされているため占有されどちらもリソースR1、申請維持します。
要件3)デッドロック
いずれかの条件が満たされない限り、デッドロックが発生しないようなデッドロックは、次の4つの条件を満たしている必要があります。
相互に排他的な条件:期間内のリソースは、国の唯一のプロセスである排他制御に割り当てられた(プリンタなど)リソースのプロセス要件、。他のリソース要求を処理する場合は、この時点では、要求プロセスは、待つことができます。
ない剥奪:完了前工程で得られた資源を使用しない場合は、強制的にのみ(のみアクティブ解除)を解放するリソース自体の方法によって得ることができる他のプロセスによって奪われることができません。
要求および保管条件:プロセスは、少なくとも一つのリソースのために維持しますが、新しいリソース要求を提案されているが、リソースが別のプロセスによって占有されているが、今回要求するプロセスがブロックされているが、資源は、彼らが利用できる持っていることのホールドを維持します。
ループ待ち状態:待機ループチェーンプロセスのリソースがあり、各リソースチェーンは、チェーン内の次の工程のために必要なプロセスを同時に取得しました。即ち、PiはリソースP(i + 1)の占有率(I = 0、1、...、N-1)を待っている待機状態集合{P1およびP2、...、PN}、の処理は、ありますP0を占有するリソースを待っているのpn。
第三には、どのようにデッドロックを避けるために、
いくつかのケースでは、デッドロックを回避することができます。デッドロックを回避するための技術の三種類:
- ロック配列(特定の順序でスレッドのロック)
- (スレッド要求が破棄されるロックの制限時間を超えた、特定の時間制限付きロックを取得しようとすると、ロックの彼らの所有物の放出)ロック時間
- デッドロックの検出
1.ロック・シーケンス
ときに複数のスレッドが同じロックの一部を必要とするが、異なる順序のロックに、デッドロックが発生しやすいです。
あなたはすべてのスレッドが同じ順序でロックを取得していることを確認することができます場合は、デッドロックは発生しません。次の例を見てください:
スレッド1: ロックA ロックB スレッド2: A待ちます (Aロック)ロックC スレッド3: A待ちます Bを待ちます Cのを待ちます
(例えば、スレッド3など)スレッドが、いくつかのロックを必要とする場合、それは決定された順序でロックを獲得しなければなりません。それはロックの後ろに取得するために、ロックの上面から注文を受けた後にのみ。
スレッド2のみロックAを取得中のスレッド3の後、例えば:ロックC(ロックがロックCを得るために必要な条件である取得翻訳者注)を取得しようとします スレッド1が既にロックが解除されるまで待機するためのスレッド2と3が必要ので、ロックAを持っているので。その後、彼らは、BまたはC、Aが正常に追加されなければならないロックする前にロックしようとします。
デッドロックを防止する効果的なロック機構であるために。しかし、このアプローチは、あなたが使用されるロックかもしれ全て事前に知っておく必要があり(翻訳者注:これらのロックとの適切なソートを行う)、時にはそれは常に予測ではありません。
2.ロック時間
デッドロックを回避するための別の方法は、ロックを取得しようとする過程で、ロック要求のスレッドをあきらめ、この上限を超えていることを意味し、タイムアウトを追加するときにロックを取得しようとしています。スレッドは、与えられた時間枠内にない場合は正常にすべての必要なロックを取得するロールバックされ、すべてのロックを解除し、ランダムな時間を待ってから再度試して、取得した、とされています。他のスレッドのためのこのランダムな待ち時間は(翻訳者注を実行し続けることができ、ロックを取得していない時にアプリケーションを同じロックを取得しよう、と聞かせする機会を持っている:最初のロック・タイムアウトが行うことができた後、いくつかの他のものを再度実行し続けます繰り返される前にロジック)がバックロック。
ここで2つのスレッドがタイムアウトが発生した後に同じ2つのロック、バックとリトライを得るために、異なる順序で試行したシーンを示す、例です:
1つのロックAスレッド 2つのロックBスレッド Bをロックする1つの試みスレッドが、ブロックされています Aをロックする2試みるスレッドが、ブロックされています B回に1のロックの試みを行うスレッド 1つのバックアップとリリースAにもスレッド 再試行する前に、ランダムに1つの待機する(例えば257ミリ秒)を通します。 A倍の2のロックの試みを行うスレッド 2バックアップし、リリースのBにもスレッド 再試行する前に、ランダムに2つの待機する(例えば、43ミリ秒)をスレッド。
上記の例では、スレッド2のスレッドリトライロック1が正常に2つのロックを取得することができる前に、200ミリ秒よりも早いです。この場合、スレッドは待ち状態にロックA 1を取得しようとします。場合は、スレッド2の終わりには、スレッド1にも成功した(スレッドまたは成功し、それらのいくつかを取得するには、2つのロックとロックを取得したスレッド1の前に別のスレッドがない限り2)2つのロックを取得することができます。
私たちはこのようなシナリオは確かにデッドロックの出現になることを信じることができないため、ロックアウトに、ので、注意してください。ロック・スレッド(他のスレッドがタイムアウトにつながる)へのアクセスはそのタスクを完了するまでに長い時間がかかるので、それであってもよいです。
また、スレッドがたくさんタイムアウトやフォールバックメカニズムがある、またはこれらのスレッドが繰り返しロックを取得することができませんでしまだ試みるが、原因となる場合でも、リソースの数と競合するために同じ時間であるかどうか。2つだけのスレッド、及びリトライのタイムアウト時間を0〜500ミリ秒に設定されている場合、この現象は発生しないことがあり、それは10件のまたは20スレッド状態である場合に異なります。等しい確率再試行時間を待っているこれらのスレッドは、はるかに高い(または非常に近いという問題が発生する)になりますので。
(翻訳者注:回避競争に順にタイムアウトと再試行のメカニズムが同時に発生しますが、近い可能性に、同じまたは2つの以上のスレッドをタイムアウト多くのスレッドは、素晴らしいことだろうと、そうであっても表示されます彼らは同時に、リトライに新たな問題をもたらした競争の新ラウンドにリードを始めますとの競争は、タイムアウト時間ので、タイムアウトにつながった後。)
そのようなAメカニズムの一つの問題は、Javaでのタイムアウトシンクブロックを設定し、同期することはできません。カスタムロックを作成、またはjava.util.concurrentのパッケージでJava5を追加ツールを使用する必要があります。ロックは複雑ではありませんカスタムを書くが、それは、この記事の範囲外です。Javaの並行処理、その後のシリーズは、ロックカスタムコンテンツをカバーします。
3.デッドロック検出
デッドロックの検出は、それがシーケンシャルロックとロック・タイムアウトを達成することができない人のために主に実現可能なシナリオではない、より良いデッドロック防止機構です。
スレッドがロックを取得するたびに、スレッドはロックされ、関連するデータ構造(地図、グラフなど)書き留めます。スレッドがロックを要求するたびに加えて、これはまた、データ構造内に記録する必要があります。
ロックを要求しているスレッドが失敗した場合、このスレッドは、デッドロックが発生しているかどうかを確認するためにロックグラフをトラバースすることができます。スレッドBはスレッドに保持されている現在のロックが要求されているかどうかを確認することができるスレッド次いで、例えば、要求ロック7のスレッドが、この時間は、ロック7は、スレッドBに保持されています。スレッドBは、そのような要求を持っている場合、デッドロックが発生している(スレッドA 1は、ロック、ロック要求7を有し、7スレッドBは、ロック、ロック要求1を有しています)。
もちろん、二つのスレッドより一般的なデッドロックはお互いのは、このような状況はより複雑であるロックホールド。待機中のスレッド、スレッドAのスレッドB待機しているスレッド、スレッドB待機中のスレッドC、Dのスレッド待機スレッドC、およびD デッドロックを検出するために、スレッド、それはB.を要求したプログレッシブすべてのロックを検出する必要があります 要求されたロックのスレッドBの初めから、スレッドをスレッドC、Dを発見して、スレッドを見つけ、スレッドD発見要求は、スレッド自身のA.を保持するためのロックです これは、デッドロックが発生して知っています。
以下、図に4つのスレッド(A、B、C及びD)及び要求されたロックの所有との間の関係です。このようなデータ構造は、デッドロックを検出するために使用することができます。
デッドロックを検出するときに、これらのスレッドはそれについて何をしますか?
1つの可能なアプローチは、背中合わせに、すべてのロックを解除して、時間のランダムな期間の後、再試行を待つことです。これと同様のシンプルなロックタイムアウト、デッドロックが唯一のフォールバックが発生したが、要求がタイムアウトしたためにロックされることはありませんだけではなくて。あなたがロックの数と競合するスレッドの数が多い場合は、ロールバックと待ち時間は、しかし、彼らはまだ繰り返しデッドロックが(編集者注:同様の理由でタイムアウトを、根本的に競争を減らすことではありません)。
彼らはロックを維持する必要があるとして、より良い解決策は、これらのスレッドのために設定された優先順位にある、(または複数の)スレッド退職させる、などのスレッドのデッドロックの残りの部分は続けました。これらのスレッドに与えられた優先順位が固定されている場合は、スレッドの数で、あなたは常に高い優先順位を持つことになります。デッドロックが発生したときに、この問題を回避するには、ランダムに優先順位を設定することができます。
[講演]コード:デッドロックケース
1 クラス Mrwang 実装Runnableを{ 2 静的オブジェクトマネー= 新しい新しいオブジェクト(); // 王Yuanwaiがお金を持って、所望の娘 3。 オブジェクト人= Bodboy.person; 4 @Override 5 公共 ボイドRUN(){ 6 しばらく(真に{) 。7 同期(マネー){ // 王Yuanwaiは、リリースに必要な、お金を取っ 8。 のSystem.out.println( "王Yuanwai :!最初のリリース" ); 。9 同期(人){ //はアルを取得しますお金の後に 10 System.out.println( "誘拐犯にお金" ); 11 } 12である } 13である } 14 } 15 } 16 クラス Bodboy 実装Runnableを{ 17 静的オブジェクト人= 新しい新しいオブジェクト(); // 誘拐犯保持人質は、所望のお金 18は、 オブジェクトマネー= Mrwang.money; 19 @Override 20れる パブリック ボイドRUN(){ 21は 、一方(真の){ 22は 同期(人物){ //捕虜を保持誘拐犯がお金の前に必要とされる 23 のSystem.out.println(「誘拐犯はあなたにお金を与えるために!」;) 24 同期(マネー){ // 解放するためにお金を得る 25 のSystem.out.println(「娘わたしを王Yuanwai " ); 26である } 27 } 28 } 29 30 } 31である } 32 パブリック クラスdeallockDemo { 33は 公共 静的 ボイドメイン(文字列[]引数){ 34が Mrwang M = 新新; Mrwang() 35 新しい新しいスレッド(M).start (); 36 BodboyのB = 新しいBodboy()。 37 新しいスレッド(B).start(); 38 } 39 }
結果:
王Yuanwaiがお金を取ったとき(ロックA)は彼にお金を与えた人質(ロックB)を、解放するために誘拐犯が必要ですが、誘拐犯の人質(ロックB)は、唯一の彼の娘を入れて、(ロックA)王Yuanwaiの所与のお金が必要です、デッドロック状態にあり、膠着状態、中2そう。
注スレッドのデッドロックは避けられない偶然ではありません。
この記事は取られます。https://www.cnblogs.com/sthu/p/9660914.html