wait notify モニターのサンプルです。
getメソッドで値を設定すると, 先に実行していた別スレッドのsetメソッドが値を返します。
setValue メソッドで値を設定した時点でgetValueで待機しているスレッドに notify で値を設定したことを通知します。そのため先にgetValueを実行しておき、値を取得した後も場合によってはさらに getValue を実行しておく必要があります。
// スレッドA
setValue(1);
setValue(2);
// スレッドB
int a = getValue();
という順で実行すると 1 の値が消えてしまうため、先に
int a = getValue(1);
が実行されている必要があります。
[WaitNotifyTest.java]
import java.util.Random;
/**
* wait notiry テストクラス
*/
public class WaitNotifyTest {
int value;
boolean request = false;
/**
* Returns the value.
* @return int
*/
public synchronized int getValue() {
System.out.println("WaitNotifyTest.getValue start -->");
while (request == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
request = false;
System.out.println("WaitNotifyTest.getValue end <--");
return value;
}
/**
* Sets the value.
* @param value The value to set
*/
public synchronized void setValue(int value) {
System.out.println("WaitNotifyTest.setValue start ==>");
this.value = value;
request = true;
notify();
System.out.println("WaitNotifyTest.setValue end <==");
}
/**
* main
*/
public static void main(String[] args) {
WaitNotifyTest wn = new WaitNotifyTest();
Thread getThread = new Thread(new GetRun(wn));
getThread.start();
Thread setThread = new Thread(new SetRun(wn));
setThread.start();
}
}
/**
* getValue のみ行うスレッド
*/
class GetRun implements Runnable {
WaitNotifyTest wn;
GetRun(WaitNotifyTest 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 SetRun implements Runnable {
WaitNotifyTest wn;
SetRun(WaitNotifyTest wn) {
this.wn = wn;
}
public void run() {
int j = 0;
while (true) {
for (int i = 0; i < 2000000; i++);
wn.setValue(++j);
System.out.println("set value=" + j);
}
}
}
実行結果
WaitNotifyTest.getValue start -->
WaitNotifyTest.setValue start ==>
WaitNotifyTest.setValue end <==
WaitNotifyTest.getValue end <--
get value=1
WaitNotifyTest.getValue start -->
set value=1
WaitNotifyTest.setValue start ==>
WaitNotifyTest.setValue end <==
WaitNotifyTest.getValue end <--
get value=2
WaitNotifyTest.getValue start -->
set value=2
WaitNotifyTest.setValue start ==>
WaitNotifyTest.setValue end <==
WaitNotifyTest.getValue end <--
set value=3
get value=3