wait和notifyAll是JDK中Object类的两个方法,主要用来线程间通讯,最经典的应用场景就是【生产者-消费者】,下面给出简单示例。
/**
* @Auothor wzx
* @Date 2017/5/7 0007
*/
public class ProducerConsumer {
public static void main(String[] args) {
Queue<Integer> buffer = new LinkedList<>();
int maxSize = 10;
Thread producer = new Thread(new Producer(buffer, maxSize));
Thread consumer = new Thread(new Consumer(buffer));
producer.start();
consumer.start();
}
static class Producer implements Runnable {
private Queue<Integer> queue;
private int maxSize;
Producer(Queue<Integer> queue, int maxSize) {
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.size() == maxSize) {
System.out.println("Queue is full,producer thread waiting for "
+ " consumer to take something from queue");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Random random = new Random();
int i = random.nextInt();
System.out.println("Producing value :" + i);
queue.add(i);
queue.notifyAll();
}
}
}
}
static class Consumer implements Runnable {
private Queue<Integer> queue;
Consumer(Queue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
System.out.println("Queue is empty,Consumer thread is waiting"
+ " for producer thread to put something in queue");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consuming value :" + queue.remove());
queue.notifyAll();
}
}
}
}
}
执行结果如下:
Producing value :-306191693
Producing value :1230823506
Producing value :-1295070113
Producing value :-330157665
Producing value :1580771896
Producing value :571342129
Producing value :1798066124
Producing value :247966176
Producing value :1149189440
Producing value :-1506596231
Queue is full,producer thread waiting for consumer to take something from queue
Consuming value :-306191693
Consuming value :1230823506
Consuming value :-1295070113
Consuming value :-330157665
Consuming value :1580771896
Consuming value :571342129
Consuming value :1798066124
Consuming value :247966176
Consuming value :1149189440
Consuming value :-1506596231
Queue is empty,Consumer thread is waiting for producer thread to put something in queue
使用wait和notifyAll方法需要注意:
1.一定要在synchronized 方法或synchronized 代码块中使用,否则JVM或抛出IllegalMonitorStateException异常;
2.使用wait方法使用while循环判断条件,避免被假唤醒;
3.synchronized 使用的一定是同个锁对象;
参考
http://javarevisited.blogspot.com/2015/07/how-to-use-wait-notify-and-notifyall-in.html#axzz4gOjkc8Yu
http://javarevisited.blogspot.com/2011/05/wait-notify-and-notifyall-in-java.html