<目次>
(1) デッドロックとライブロックとは?両者の違いやサンプルプログラムをご紹介
(1-1) デッドロック
(1-1-1) 概要
(1-1-2) サンプルプログラム
(1-2) ライブロック
(1-2-1) 概要
(1-2-2) サンプルプログラム
(1) デッドロックとライブロックとは?両者の違いやサンプルプログラムをご紹介
(1-1) デッドロック
(1-1-1) 概要
(1-1-2) サンプルプログラム
●デッドロックを引きおこすクラス
public class DeadLockSampleClass { private static String strA = "abcde"; private static String strB = "fghij"; public void someFunction1() { synchronized(strA) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread#1 : strB の開放待ち"); synchronized(strB) { String strC = strA + strB; System.out.println("Thread#1 : 完成品 = "+strC); } } } public void someFunction2() { synchronized(strB) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread#2 : strA の開放待ち"); synchronized(strA) { String strD = strA + strB; System.out.println("Thread#2 : 完成品 = "+strD); } } } }
●上記を実行するmain文
public class DeadLockSample { static final DeadLockSampleClass dlock = new DeadLockSampleClass(); public static void main(String args[]) { Thread t1 = new Thread(new Runnable() { public void run() { dlock.someFunction1();; } }); t1.start(); Thread t2 = new Thread(new Runnable() { public void run() { dlock.someFunction2();; } }); t2.start(); } }
(1-2) ライブロック
(1-2-1) 概要
ライブロックもデッドロックと非常に似ていますが、相違点としてライブロックに関係するプロセスは、相手の状態によって、自身の状態も定期的に変化していき、その結果としてお互いに進展しない状態を表しています。
有名?な現実世界の例えとして、二人の人が細い道ですれ違う際に、お互いに同じ方向に譲り合いを繰り返し、ぶつかりそうになりながら進めない状態ってありますよね?その状態がライブロックに似ています。
(1-2-2) サンプルプログラム
●道を通るために相手(Bさん)に道を譲る「Aさん」
public class LiveLockPerson1 { //# 最初は「右」に避ける private boolean move_right = true; //# true=右側に避けた、false=左側に避けた //# 相手に道を譲るメソッド public void moveToPass(LiveLockPerson2 lp2) { while(this.move_right==lp2.hasMovedRight()) { try { Thread.sleep(1000); //# では、私が反対方向に避けますので、どうぞお通りくだだい System.out.println("「A」です。私が反対方向に避けますので、どうぞお通りください"); this.move_right = moveOpposite(this.move_right); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("「A」です。無事に通れました。"); } //# どちらの方向に避けたかどうか?を教えるメソッド public boolean hasMovedRight() { //# true=右側に避けた、false=左側に避けた return this.move_right; } //# 反対方向に避けるメソッド public boolean moveOpposite(boolean isRight) { //# いま右なら左に避ける if(isRight==true) { return false; } //# いま左なら右に避ける else { return true; } } }
↓
●道を通るために相手(Aさん)に道を譲る「Bさん」
public class LiveLockPerson2 { //# 最初は「右」に避ける private boolean move_right = true; //# true=右側に避けた、false=左側に避けた //# 相手に道を譲るメソッド public void moveToPass(LiveLockPerson1 lp1) { while(this.move_right==lp1.hasMovedRight()) { try { Thread.sleep(1000); //# では、私が反対方向に避けますので、どうぞお通りくだだい System.out.println("「B」です。私が反対方向に避けますので、どうぞお通りください"); this.move_right = moveOpposite(this.move_right); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("「B」です。無事に通れました。"); } //# どちらの方向に避けたかどうか?を教えるメソッド public boolean hasMovedRight() { //# true=右側に避けた、false=左側に避けた return this.move_right; } //# 反対方向に避けるメソッド public boolean moveOpposite(boolean isRight) { //# いま右なら左に避ける if(isRight==true) { return false; } //# いま左なら右に避ける else { return true; } } }
↓
●両者のスレッドを起動するmain文
public class LiveLockSample { static final LiveLockPerson1 lp1 = new LiveLockPerson1(); static final LiveLockPerson2 lp2 = new LiveLockPerson2(); public static void main(String args[]) { Thread t1 = new Thread(new Runnable() { public void run() { lp1.moveToPass(lp2); } }); t1.start(); Thread t2 = new Thread(new Runnable() { public void run() { lp2.moveToPass(lp1); } }); t2.start(); } }