例子:
package com.waitnotify;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class WaitNotify {
static boolean flag = true;
static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
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 (object) {
try {
while (flag) {
System.out.println(Thread.currentThread().getName() + " hold lock @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()) + ", flag is true.");
object.wait();
}
System.out.println(Thread.currentThread().getName() + " hold lock again @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()) + ", flag is false.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 生产者
static class Notify implements Runnable {
@Override
public void run() {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() + " hold lock @"
+ new SimpleDateFormat("HH:mm:ss")
.format(new Date()));
object.notifyAll();
flag = false;
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() + " hold lock again @"
+ new SimpleDateFormat("HH:mm:ss")
.format(new Date()));
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
消费者模型
synchronized (lock) {
while (condition) {
lock.wait();
}
......
}
生产者模型
synchroinzed(lock) {
lock.notify(); // 或lock.notifyAll()
......
}
过程
消费者线程通过获取锁,执行代码,在代码中通过wait()进入等待队列(WaitQueue),并且释放锁。接着生产者线程获取锁,执行代码,在代码中通过notify()函数通知消费者从等待队列中出列进入同步队列(SynchronizedQueue)处于BLOCKED状态,直到生产者线程运行完毕释放锁,消费者线程获取锁,并通过条件判断继续执行代码。需要注意,生产者使用notify()或notifyAll()函数并没有立即释放锁,只有当线程运行完毕才会释放。