一個線程做了修改對象值(或其他)操作,另一個線程感覺到了變化,然後進行相應操作,整個過程開始于一個線程,最終執行又是另外一個線程。前者是生産者,後者是消費者,這種模式隔離了“做什麼”和“怎麼做”,實作了業務上的解耦。
其具體實作方式是線程A調用了對象O的wait()方法進入等待狀态,另一個線程B調用對象B的notify() or notifyAll()方法,線程A收到通知後從對象O的wait()方法傳回,進而執行後續操作 。其邏輯流程如下:
thread 得到object 的 monitor, 調用 object.wait()
- 釋放object 的 monitor, thread wait;
thread 得到 object 的 monitor, 調用 object.notify()
- 激活thread, 釋放object 的 monitor;
thread 得到 object 的 monitor, 從object.wait()傳回, thread接着執行.
示範demo如下:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class WaitNotify {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws Exception {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable {
@Override
public void run() {
synchronized (lock) {
while (flag) {
try {
System.out.println(Thread.currentThread() + " flag is true. wait @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.wait();
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread() + " flag is false. running @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()));
}
}
}
static class Notify implements Runnable {
@Override
public void run() {
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock. notify @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()));
lock.notifyAll();
flag = false;
SleepUtils.second(5);
}
synchronized (lock) {
System.out.println(Thread.currentThread() + " hold lock again. sleep @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()));
SleepUtils.second(5);
}
}
}
}