前提:生產者不斷地生產產品,消費者取走生產者生產的產品。生產者生產出產品後將其放到一個區域之中,消費者從這個地方去除數據java
分析: 1.是否設計多線程?是,生產者,消費者 2.是否涉及到共享數據?有!考慮線程的安全 3.此共享數據是誰?即爲產品的數量 4.是否設計線程的通訊?存在生產者與消費者的通訊
public class Clerk { //當前商品數量 private int product = 0; public synchronized void addProduct() {//同步控制併發 while (product >= 5) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } product++; System.out.println(Thread.currentThread().getName() + "生成了" + product + "產品"); notifyAll();//喚起全部阻塞的多線程 //notify 只能通知一個在等待的對象,其餘在等待的對象不會通知,會致使多線程的併發問題 } public synchronized void consumProduce() { while (product <= 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消費" + product + "產品"); product--; notifyAll(); } }
public class Consumer implements Runnable {//消費者 Clerk clerk; public Consumer(Clerk clerk){ this.clerk = clerk; } @Override public void run() { System.out.println("消費者消費產品"); while (true){ clerk.consumProduce(); } } }
public class Product implements Runnable {//生產者 Clerk clerk; public Product(Clerk clerk){ this.clerk = clerk; } @Override public void run() { System.out.println("生產者生產產品"); for(int i=0;i<10;i++){ clerk.addProduct(); } } }
多線程測試類: public class TestProductConsume { public static void main(String args[]){ Clerk clerk = new Clerk(); for(int i = 0; i < 4;i++){ Product p1 = new Product(clerk); Consumer c1 = new Consumer(clerk); Thread t1 = new Thread(p1); Thread t2 = new Thread(c1); t1.setName("生產者"+i); t2.setName("消費者"+i); t1.start(); t2.start(); } } }
notify只會通知一個在等待的對象,而notifyAll會通知全部在等待的對象,而且全部對象都會繼續運行安全
被wait的線程,想要繼續進行的話,必須知足2個條件:多線程
1.通過有其餘線程notify或notifyAll,而且當前線程被通知到併發
2.通過和其餘線程進行鎖競爭,成功獲取鎖ide
notify 僅僅通知一個線程,而且咱們不知道哪一個線程會收到通知,然而 notifyAll 會通知全部等待中的線程。換言之,若是隻有一個線程在等待一個信號燈,notify和notifyAll都會通知到這個線程。但若是多個線程在等待這個信號燈,那麼notify只會通知到其中一個,而其它線程並不會收到任何通知,而notifyAll會喚醒全部等待中的線程。測試