wait(),notify(),notifyAll()的理解与使用
这三个方法由于需要控制对对象的控制权(monitor),所以属于Object而不是属于线程。
wait(),会把持有该对象线程的对象控制权交出去,然后处于等待状态。
notify(),会通知某个正在等待这个对象的控制权的线程可以继续运行。
nofifyAll(),会通知所有等待这个对象控制权的线程继续运行,如果有多个正在等待该对象控制权时,具体唤醒哪个线程,就由操作系统进行调度。
注意:
1.生产者,消费者必须要对同一份资源进行操作。
2.无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)
生产者:
package com.currentPro.waitAndnotify; import java.util.ArrayList; import java.util.List; public class Producer implements Runnable{ private List<Integer> taskQueue = new ArrayList<Integer>(); //生产的量 private final int MAX_CAPACITY; public Producer(List<Integer> sharedQueue,int size){ this.taskQueue = sharedQueue; this.MAX_CAPACITY = size; } @Override public void run() { int counter = 1; while (true) { try { synchronized (taskQueue) { while (taskQueue.size() == MAX_CAPACITY) { System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size()); taskQueue.wait(); } Thread.sleep(1000); taskQueue.add(counter); System.out.println("Produced: " + counter); counter++; //唤醒正在等待的消费者,但是消费者是不是能获取到资源,由系统调度。 taskQueue.notifyAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
消费者:
package com.currentPro.waitAndnotify; import java.util.List; public class Consumer implements Runnable{ private final List<Integer> taskQueue ; public Consumer(List<Integer> sharedQueue){ this.taskQueue = sharedQueue; } @Override public void run() { while (true) { try { synchronized (taskQueue) { while (taskQueue.isEmpty()) { System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size()); taskQueue.wait(); } Thread.sleep(1000); int i = (Integer) taskQueue.remove(0); System.out.println("Consumed: " + i); taskQueue.notifyAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } }
测试代码:
package com.currentPro.waitAndnotify; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) throws InterruptedException { //共享资源 List<Integer> taskQueue = new ArrayList<Integer>(); int MAX_CAPACITY = 5; //创建生产者线程 Thread producer = new Thread(new Producer(taskQueue,MAX_CAPACITY),"producer"); //创建消费者线程 Thread consumer = new Thread(new Consumer(taskQueue),"consumer"); consumer.start(); Thread.sleep(2000); producer.start(); } }
参考资料
http://longdick.iteye.com/blog/453615
http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/
http://www.cnblogs.com/dolphin0520/p/3920385.html