如何在 Java 中正确使用 wait, notify 和 notifyAll?

java

简介

    wait,notify,notifyAll,都是属于object对象提供的方法,但在实际工作中怎么使用这几个方法,确是很多程序员清楚,不够明白,在群里问,有人说,哪个线程想wait,就用

 需等待线程.wait(),就跟Thread.sleep()一样,唤醒也一样,这样显然是不对的。

   在 Java 中可以用 wait、notify 和 notifyAll 来实现线程间的通信。。举个例子,如果你的Java程序中有两个线程——即生产者和消费者,那么生产者可以通知消费者,让消费者开始消耗数据,因为队列缓 冲区中有内容待消费(不为空)。相应的,消费者可以通知生产者可以开始生成更多的数据,因为当它消耗掉某些数据后缓冲区不再为满。

 1、废话不多说,直接看demo吧

package hello.wait_notify;

import java.util.LinkedList;

import java.util.List;

import java.util.Random;

import java.util.concurrent.ConcurrentLinkedQueue;

/**

* Created by jacky on 2017/3/25 0025.

*/

public class Waint_Notify {

public static void main(String args[])

{

ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

int maxSize = 10;

Thread producer = new Producer(queue, maxSize, "PRODUCER");

Thread consumer = new Consumer(queue, maxSize, "CONSUMER");

producer.start();

consumer.start();

}

static class Producer extends Thread {

private ConcurrentLinkedQueue queue;

private int maxSize;

public Producer(ConcurrentLinkedQueue queue, int maxSize, String name) {

super(name);

this.queue = queue;

this.maxSize = maxSize;

}

@Override

public void run() {

while (true) {

synchronized (queue) {

while (queue.size() == maxSize) {

try {

System.out.println("队列中已经满了,等待消费者消费!");

queue.wait();

} catch (Exception ex) {

ex.printStackTrace();

}

}

Random random = new Random();

int i = random.nextInt();

System.out.println("Producing value : " + i);

queue.add(i);

queue.notifyAll();

}

}

}

}

static class Consumer extends Thread {

private ConcurrentLinkedQueue queue;

private int maxSize;

public Consumer(ConcurrentLinkedQueue queue, int maxSize, String name) {

super(name);

this.queue = queue;

this.maxSize = maxSize;

}

@Override

public void run() {

while (true) {

synchronized (queue) {

while (queue.isEmpty()) {

System.out.println("队列已经空了,等待生产者放数据" );

try {

queue.wait();

} catch (Exception ex) {

ex.printStackTrace();

}

}

System.out.println("Consuming value : " + queue.remove());

queue.notifyAll();

}

}

}

}

}

2、结果

3、总结

1. 你可以使用wait和notify函数来实现线程间通信。你可以用它们来实现多线程(>3)之间的通信。

2. 永远在synchronized的函数里使用wait、notify和notifyAll,不然Java虚拟机会生成 IllegalMonitorStateException。

3. 永远在while循环里而不是if语句下使用wait。这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。

4. 永远在多线程间共享的对象(在生产者消费者模型里即缓冲区队列)上使用wait。

5. 基于前文提及的理由,更倾向用 notifyAll(),而不是 notify()。

以上是 如何在 Java 中正确使用 wait, notify 和 notifyAll? 的全部内容, 来源链接: utcz.com/z/392970.html

回到顶部