如何使用wait
- 在synchronized的函数或对象里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException
- 永远在多线程间共享的对象上使用wait,也就是在synchronized的对象上。
永远在循环里调用 wait 和 notify,不是在 If 中
// The standard idiom for calling the wait method in Java
synchronized (sharedObject) {
while (condition) {
sharedObject.wait();
// (Releases lock, and reacquires on wakeup)
}
// do action based upon condition e.g. take or put into queue
}
生产者消费者示例
/**
* 生产者消费者示例
* <p>生成N个 消费N个</p>
*/
public class ProducerConsumerTest {
class Producer extends Thread {
private Queue<Integer> queue;
private int maxSize;
Producer(Queue<Integer> queue, int maxSize) {
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run() {
synchronized (queue) {
//while 一定要放在同步代码内部
while (true) {
//如果要交替打印,可将条件改为: !queue.isEmpty()
while (queue.size() == maxSize) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产1个");
queue.add(1);
//如果多个消费者 可改为notifyAll
queue.notify();
}
}
}
}
class Consumer extends Thread {
private Queue<Integer> queue;
Consumer(Queue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
synchronized (queue) {
while (true) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费1个");
queue.remove();
queue.notify();
}
}
}
}
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
ProducerConsumerTest test = new ProducerConsumerTest();
Producer producer = test.new Producer(queue, 10);
Consumer consumer = test.new Consumer(queue);
producer.start();
consumer.start();
}
}
效果如下: