wait() 和notify() nofifyAll()
阿新 • • 發佈:2018-12-09
這三個方法由於需要控制對物件的控制權(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(); } }