java多執行緒中等待/通知機制
阿新 • • 發佈:2019-02-20
一個執行緒做了修改物件值(或其他)操作,另一個執行緒感知到了變化,然後進行相應操作,整個過程開始於一個執行緒,最終執行又是另外一個執行緒。前者是生產者,後者是消費者,這種模式隔離了“做什麼”和“怎麼做”,實現了業務上的解耦。
其具體實現方式是執行緒A呼叫了物件O的wait()方法進入等待狀態,另一個執行緒B呼叫物件B的notify() or notifyAll()方法,執行緒A收到通知後從物件O的wait()方法返回,進而執行後續操作 。其邏輯流程如下:
thread1 得到object1 的 monitor, 呼叫 object1.wait()
- 釋放object1 的 monitor, thread1 wait;
thread2 得到 object1 的 monitor, 呼叫 object1.notify()
- 啟用thread1, 釋放object1 的 monitor;
thread1 得到 object1 的 monitor, 從object1.wait()返回, thread1接著執行.
演示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);
}
}
}
}