Java中通過wait和notify來實現生產者和消費者模式
阿新 • • 發佈:2019-01-31
今天通過介紹一下如何通過wait和notify來實現生產者和消費者模式。
通過synchronized同步程式碼塊實現執行緒的同步操作,從而保證資料的一致性。下面具體介紹一下這個模式的實現過程。
1.首先編寫一個生產者類:
2.其次編寫一個消費者類:public class Producer implements Runnable { private PublicBox box; public Producer(PublicBox box) { this.box = box; } @Override public void run() { int i=0; while(true){ try { System.out.println("生產者序號:" + i); i++; Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } box.increace(); } } }
3.最後編寫倉庫類:public class Consumer implements Runnable { private PublicBox box; public Consumer(PublicBox box) { this.box = box; } @Override public void run() { int i=0; while(true){ try { System.out.println("消費者序號" + i); i++; Thread.sleep(3000); } catch (InterruptedException e) { // TODO: handle exception e.printStackTrace(); } box.decreace(); } } }
打印出來的部分結果: 這個執行過程有些人可能會有些疑問,我在這裡具體描述一下這整個過程是如何實現的。 在這裡因為生產者所休眠的時間比消費者短,所以生產者出現的頻率會比消費者高一些。 1:首先是生產者和消費者都新建了各自的序號並打印出來。 2:因為是消費者先啟動的,所以首先訪問decreace同步塊,可是因為條件不符合所以被wait了。 3:消費者被wait之後,生產者就開始啟動increace同步塊生產了。生產者一生產就會呼叫notify方法,這個時候第二步已經被wait的執行緒就會被喚醒,接著執行wait之後的程式碼。但是這裡需要注意的是並不是生產者呼叫notify方法,消費者就會馬上被喚醒執行接下來的程式碼。因為喚醒和執行都需要時間,這個過程可能生產者又生成新的產品了嗎,也有可能是消費者馬上被執行。 4:之後的過程就是按照前面三步驟進行迴圈輸出的。 這個模式下的生產者消費者主要是通過synchronized 同步程式碼塊來保證product這個變數的一致性。保證product變數在多個執行緒的呼叫的過程中,執行緒之間不會發生互相干擾,按正確的順序執行這些過程。 如果對上面的內容還有什麼疑義或者問題都可以加我QQ:208017534諮詢。public class PublicBox { private int product = 0; public synchronized void increace() { while (product == 5) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } product++; System.out.println("產品生產成功!目前產品的儲存量:"+product); notify(); } public synchronized void decreace() { while (product == 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } product--; System.out.println("產品消費成功!目前產品的儲存量:"+product); notify(); } public static void main(String[] args) { PublicBox box = new PublicBox(); Consumer con = new Consumer(box); Producer pro = new Producer(box); Thread t1 = new Thread(con); Thread t2 = new Thread(pro); t1.start(); t2.start(); } }