<目次>
(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();
}
}
