1. 使用注意事项
1、永远在synchronized的函数或对象里使用wait、notify和notifyAll,不然Java虚拟机会生成IllegalMonitorStateException。
2、永远在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。
3、永远在多线程间共享的对象上使用wait。
4、notify随机通知一个阻塞在对象上的线程;notifyAll通知阻塞在对象上所有的线程。
2. 代码示例
2.1 生产者
public class Producer implements Runnable{
private Queue<Integer> queue;
private int maxSize;
public Producer(Queue<Integer> queue, int maxSize){
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true){
synchronized (queue){
while (queue.size() == maxSize){
try{
System.out.println("Queue is Full");
queue.wait();
}catch (InterruptedException ie){
ie.printStackTrace();
}
}
Random random = new Random();
int i = random.nextInt();
System.out.println("Produce " + i);
queue.add(i);
queue.notifyAll();
}
}
}
}
2.2 消费者
public class Consumer implements Runnable{
private Queue<Integer> queue;
private int maxSize;
public Consumer(Queue<Integer> queue, int maxSize){
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true){
synchronized (queue){
while (queue.isEmpty()){
System.out.println("Queue is Empty");
try{
queue.wait();
}catch (InterruptedException ie){
ie.printStackTrace();
}
}
int v = queue.remove();
System.out.println("Consume " + v);
queue.notifyAll();
}
}
}
}
2.3 Main
public class Main {
public static void main(String[] args){
Queue<Integer> queue = new LinkedList<>();
int maxSize = 10;
Producer p = new Producer(queue, maxSize);
Consumer c = new Consumer(queue, maxSize);
Thread pT = new Thread(p);
Thread pC = new Thread(c);
pT.start();
pC.start();
}
}
3. 参考
https://www.cnblogs.com/plmnko/archive/2010/10/15/1851854.html