最初の完全なコード
その後の再順序変性ブロックは、対応する結論を得
1 // デッドロック感じる書き込みしようとする 2 パブリック クラス{デッドロックを 3。 公共 静的 ボイドメイン(文字列[]引数){ 4。 オブジェクトO1 = 新しい新しいオブジェクト(); 5 オブジェクトO2 = 新しい新しいオブジェクト(); 6は、 // 2の作成対象物 7 // スレッド二つのスレッドを作成し 8。 スレッドTlの= 新しい新しいスレッド(新しい新しいプロセス1(O1、O2)); // 二つのスレッドT1、T2を共有同じ2つのO1、O2オブジェクト 9。 スレッドT2 = 新しい新スレッド(新新プロセス2(O1、O2)); 10 T1.setName( "T1" ) 。11 T2.setName( "T2" ); 12である // スターRUNビット 13は T1.start(); // 実行---- T2 14 // T1を実行-----を 15 T2.start(); 16 17 18である } 19 } 20は // 最初の書き込みスレッドクラス。 図21は、ある クラスプロセス1 実装Runnableを{ 22は 、オブジェクトO1、O2、 23は プロセス1(オブジェクトO1、O2オブジェクト){ 24 この .o1 = 01; 25 この .o2 = O2。 26である } 27 公共 ボイドRUN(){ 28 // 最初のロック次いでO1 O2ロック 29 同期(O1){ 30 のtry { 31である のThread.sleep(1000); // ロックO1及び睡眠LS 32 } キャッチ(例外E) { 33であり ; e.printStackTrace() 34である } 35 同期(O2){ IF(..にThread.currentThread()のgetName()に等しい( "T1")){ // T1が正常に実行され、及びO2 2 T1 O1出力のリターンロック 36 のSystem.out.println( "----- T1実行" );} 37 [ もし(。。にThread.currentThread()のgetName()は( "T2"に等しい)){ 38 のSystem.out.println( "---- T2実行" );} 39 } 40 } 41 } 42 } 43 44 クラスプロセス2 実装のRunnable { 45 オブジェクトO1、O2。 46 プロセス2(オブジェクトO1、オブジェクトO2){ 47 この .o1 = O1。 48 この .o2 = O2。 49 } 50 公共 ボイドラン(){ 51 // 先锁O2再锁O2 52れる 同期(O2){ // ロックO2及び睡眠LS 53である トライ{ 54である のThread.sleep(1000 ); 55 } 56で キャッチ{(例外E) 57である e.printStackTrace(); 58 } 59 同期(O1){ 60 IF(..にThread.currentThread()のgetName()に等しい( "T1" )){ 61である のSystem.out.println( "実行----- T1" );} 62は、 IF(にThread.currentThread()のgetName(。 ).equals( "T2")){ //// 成功実行T2、T2とリターン出力後O1、O2 2つのロック 63 System.out.println( "---- T2実行" );} 64 } 65 } 66 } 67 }
実験の重要な点はのThread.sleep()を使用することで、スレッドのスリープ、異なるロックを達成し、O1、O2の状況のロックを解除します。
ブロックA(T1方法で実行)。
RUNボイドパブリック(){ 28 //最初のロックは、その後、O1、O2ロック 同期(O1){29 30試み{ //ロックO1及び睡眠LS; 31のThread.sleep(1000)であり、 32}キャッチ(例外E){ 33がEであります.printStackTrace(); 34}は {35同期(O 2)の後に(場合 {// T1 ..にThread.currentThread()のgetName()は( "T1")に等しい) 成功した実装、t1とリターン出力O1、O2 2つのロック 36 System.out.println( "実行----- T1");} 37 [IF(にThread.currentThread()のgetName()に等しい( "T2")..){ 38のSystem.out.println(「---です-T2「)を実行している;} 39} 40} 41}れます
コードブロックB(方法T2で実行)。
公共 のボイドの実行(){ 51 // 先锁O2再锁O2 52 同期(O2){ // 锁住O2并睡1秒 53 のtry { 54のThread.sleep(1000年); 55 } 56 キャッチ(例外e){ 57 e.printStackTrace(); 58 } 59 同期(O1){ 60 であれば(にThread.currentThread()のgetName()に等しい( "T1"。。 )){ 61のSystem.out.println( "t1が実行-----" );} 62は、 IF(にThread.currentThread()。関連項目GetName()。等号( "T2")){ //// O2 2つのロックO1成功実行T2後、T2とリターン出力 63のSystem.out.println(「---実行-T2 " );} 64}
実験1:ブロックAとBのThread.sleep(1000);文は、コメント
出力結果:確率Dading
----- T1走行
---- T2ランニング
小さな確率出力
-----実行T2
T1以上のCPU時間ブロックへの容易なアクセスは、すべての文が終了し、アンロックO1、O2、のみT2.star(実施後されるため、このような結果を実行---- T1)が発生します声明、出力T2ランニング
実験2:ブロックAのThread.sleep(1000); Zhushidiao
出力:出力には大きなチャンスとなります
----- T1ランニング
:-------- LSの間隔の後
---- T2を実行しています
声明のは)(T1.starを実行しているので
実行文のスレッドT1が終了すると、スレッドT2は、この時間O1 O2ロック解除時に、CPUのタイムスライスを取得するために始めました。T2は、(スリープ書を含む)のブロックを正常に行うことができます実行されます
そこデッドロックの小さなチャンスになります。このときCPUのタイムスライスを受けた最初T2、およびO2ロックされ、スレッドは1秒を停止し、T1 O1のステートメントを実行するには、この時間は十分にロックされますので、O1 O2ロックを返すことができません、デッドロックを形成
実験3:ブロックAとコメントしているBのThread.sleep(1000)ブロック
出力:
ない出力は、T1またはT2は、CPUのタイムスライスを取得するかどうか、ロックが削除され、スレッドは1秒をブロックされているので、この時間は、その後、別のロックにロックO2 O1を別のスレッドを拾うために十分であるが返すことはできません必要があります、T1、T2の実行文がダウンして継続することができませんでした、プログラムがロックされています。