1. 程式人生 > 實用技巧 >wait()和nodify()方法的理解

wait()和nodify()方法的理解

7.4 關於Object類中的wait和notify方法。(生產者和消費者模式。) 第一:wait和notify方法不是執行緒物件的方法,是java中任何一個java物件都有的方法,因為這兩個方式是Object類中自帶的。 wait方法和notify方法不是通過執行緒物件呼叫的, 不是這樣的:t.wait(),也不是這樣的:t.notify .. 不對。 第二:wait()方法作用? Object o = new Object(); o.wait(); 表示:讓正在o物件上活的執行緒進入等待狀態,無期限等待,直到被喚醒為止。 o.wait();方法的呼叫,會讓“當前執行緒(正在o物件上活動的執行緒)”進入等待狀態。 第三:notify()方法作用? Object o = new Object(); o.nodify(); 表示: 喚醒正在o物件上等待的執行緒。 還有一個nodifyAll()方法: 這個方法是喚醒o物件上處於等待的所有執行緒。 案例:
package
com.javaSe.Thread; import javax.management.relation.RelationNotFoundException; import java.util.ArrayList; import java.util.List; /* 1 使用wait方法和notify方法實現“生產者和消費者模式” 2 什麼是“生產者和消費者模式”? 生產執行緒負責生產,消費執行緒負責消費。 生產執行緒和消費執行緒要達到均衡。 這是一種特殊的業務需求,在這種特殊的情況下需要使用wait方法和notify方法。 3 wait和notify方法不是執行緒物件的方法,是普通java物件都有的方法。 4 wait方法和notify方法建立線上程同步的基礎之上,因為多執行緒要同時操作一個倉庫。有執行緒安全問題。 5 wait方法作用:o.wait()讓正在o物件上活動的執行緒t進入等待狀態,並且釋放掉t執行緒之前佔有的o物件的鎖。 6 notify方法作用:o.notify()讓正在o物件上等待的執行緒喚醒,只是通知,不會釋放o物件上之前佔有的鎖。 7 模擬這樣一個需求: 倉庫我們採用List集合。 List集合中假設只能儲存1個元素。 1個元素就表示倉庫滿了。 如果List集合中元素個數是0,就表示倉庫空了。 保證List集合中永遠都是最多儲存1個元素。 必須做到這種效果:生產1個消費1個。
*/ public class ThreadTest16 { public static void main(String[] args) { // 建立1個倉庫物件,共享的 List list = new ArrayList(); // 建立兩個執行緒物件 // 生產者執行緒 Thread t1 = new Thread(new Producer(list)); // 消費者執行緒 Thread t2 = new Thread(new Consumer(list)); t1.setName(
"生產者執行緒"); t2.setName("消費者執行緒"); t1.start(); t2.start(); } } // 生產執行緒 class Producer implements Runnable{ // 倉庫 private List list; public Producer(List list){ this.list = list; } @Override public void run() { // 一直生產 // 使用死迴圈來模擬一直生產 while (true){ // 給倉庫物件list加鎖。 synchronized (list){ if (list.size() > 0){ // 大於0,說明倉庫中已經有一個元素了 // 當前執行緒進入等待狀態,並且釋放Producer之前佔有的list集合的鎖 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 程式能夠執行到這裡說明倉庫是空的,可以生產 Object obj = new Object(); list.add(obj); System.out.println(Thread.currentThread().getName() + "--->" + obj); // 喚醒消費者進行消費 list.notify(); } } } } // 消費執行緒 class Consumer implements Runnable{ // 倉庫 private List list; public Consumer(List list){ this.list = list; } @Override public void run() { // 一直消費 while (true){ synchronized (list){ if (list.size() == 0){ // 倉庫已經空了 // 消費者執行緒等待,釋放掉list集合的鎖。 try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 程式執行到這裡,說明倉庫中有資料進行消費。 Object o = list.remove(0); System.out.println(Thread.currentThread().getName() + "--->" + o); // 喚醒生產者生產 list.notify(); } } } }