wait notify サンプル1の改良版です。 getValue を2回呼び出しても1回目に設定した値が保持される方法です。 WaitNotifyTest2.java ではわざとgetValueよりsetValueのがより多く実行されるようにしています。これだと WaitNotifyTest1.java ではsetValueによってまだ取得されていない値が上書きされすべての値を取得できませんが、setValue, getValue 両方で wait, notifyを利用することですべての値を取得可能になり、値の取りこぼしはなくなります。
[WaitNotifyTest2.java]
/**
* wait notiry テストクラス
*/
public class WaitNotifyTest2 {
int value;
boolean request = false;
/**
* Returns the value.
* @return int
*/
public synchronized int getValue() {
System.out.println("WaitNotifyTest2.getValue start -->");
while (request == false) {
try {
wait();
} catch (InterruptedException e) {}
}
request = false;
notify();
System.out.println("WaitNotifyTest2.getValue end <--");
return value;
}
/**
* Sets the value.
* @param value The value to set
*/
public synchronized void setValue(int value) {
System.out.println("WaitNotifyTest2.setValue start ==>");
while (request) {
// 既に値が設定されているので取得されるまで待つ
try {
wait();
} catch (InterruptedException e) {}
}
request = true;
this.value = value;
notify();
System.out.println("WaitNotifyTest2.setValue end <==");
}
/**
* main
*/
public static void main(String[] args) {
WaitNotifyTest2 wn = new WaitNotifyTest2();
Thread getThread = new Thread(new GetRun2(wn));
getThread.start();
Thread setThread = new Thread(new SetRun2(wn));
setThread.start();
}
}
/**
* getValue のみ行うスレッド
*/
class GetRun2 implements Runnable {
WaitNotifyTest2 wn;
GetRun2(WaitNotifyTest2 wn) {
this.wn = wn;
}
public void run() {
while (true) {
for (int i = 0; i < 2000000; i++);
System.out.println("get value=" + wn.getValue());
}
}
}
/**
* setValue のみ行うスレッド
*/
class SetRun2 implements Runnable {
WaitNotifyTest2 wn;
SetRun2(WaitNotifyTest2 wn) {
this.wn = wn;
}
public void run() {
int j = 0;
while (true) {
wn.setValue(++j);
// System.out.println("set value=" + j);
}
}
}
実行結果
WaitNotifyTest2.getValue start -->
WaitNotifyTest2.setValue start ==>
WaitNotifyTest2.setValue end <==
WaitNotifyTest2.getValue end <--
get value=1
WaitNotifyTest2.getValue start -->
WaitNotifyTest2.setValue start ==>
WaitNotifyTest2.setValue end <==
WaitNotifyTest2.getValue end <--
get value=2
WaitNotifyTest2.getValue start -->
WaitNotifyTest2.setValue start ==>
WaitNotifyTest2.setValue end <==
WaitNotifyTest2.getValue end <--
get value=3
WaitNotifyTest2.getValue start -->
WaitNotifyTest2.setValue start ==>
WaitNotifyTest2.setValue end <==
WaitNotifyTest2.getValue end <--
get value=4
WaitNotifyTest2.getValue start -->
WaitNotifyTest2.setValue start ==>
WaitNotifyTest2.setValue end <==
WaitNotifyTest2.getValue end <--
get value=5