1. 程式人生 > >Java基礎之多執行緒-多生產多消費

Java基礎之多執行緒-多生產多消費

使用場景請看上一篇部落格Java基礎之多執行緒-多生產多消費

話不多說,直接上程式碼:
顧客:

package cn.itcast.day07.demo02;


public class MultiConsumer implements Runnable {

    private final Object LOCK;

    public MultiConsumer(Object lock) {
        this.LOCK = lock;
    }

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        while
(true) { synchronized (LOCK) { while (MultiMain.products <= 0) { // 這裡必須使用while,不能用if。 System.out.println(name + "因為沒有包子,等待……"); try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name + "吃掉了包子:"
+ MultiMain.products--); LOCK.notifyAll(); // 通知對方兩個廚子趕緊做,同時我的同伴顧客也會收到通知 } // sync try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } // while } }

廚子:

package cn.itcast.day07.demo02;

public
class MultiProducer implements Runnable { private final Object LOCK; public MultiProducer(Object lock) { this.LOCK = lock; } @Override public void run() { String name = Thread.currentThread().getName(); while (true) { synchronized (LOCK) { while (MultiMain.products >= 100) { // 這裡必須使用while,不能用if。 System.out.println(name + "因為包子太多,等待……"); try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name + "做出了包子:" + ++MultiMain.products); LOCK.notifyAll(); // 通知對方兩個顧客趕緊吃,同時我的同伴廚子也會收到通知 } // sync try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } // while } }

Main方法:

package cn.itcast.day07.demo02;

public class MultiMain {

    public static int products = 50; // 初始50個包子

    public static void main(String[] args) {
        Object lock = new Object();

        new Thread(new MultiConsumer(lock), "[顧客1]").start();
        new Thread(new MultiConsumer(lock), "[顧客2]").start();
        new Thread(new MultiProducer(lock), "[廚子A]").start();
        new Thread(new MultiProducer(lock), "[廚子B]").start();
    }

}

注:多生產多消費與單生產單消費的區別

區別在於在鎖內判斷包子數量的時候用的是if判斷還是while判斷:

單生產單消費二者都可以使用,但是建議使用if。
多生產多消費必須使用while,不可使用if。
if與while區別如下:
若使用if判斷,在執行LOCK.wait()方法之後,若在重新獲得鎖之後,便接著向下執行,不會再重新走一遍if語句判斷一下包子的數量,這在單生產單消費模式中並沒有什麼問題,因為只有一個顧客,沒有別的人跟他搶包子;
但是在多生產多消費的模式下,如果包子還有一個,你不能保證在你沒有吃的情況下另一位顧客也沒有吃,所以在你獲得鎖之後要再次判斷一下包子的數量,然而if並不支援這個操作,就要用到while了。

多生產多消費的模型如下
這裡寫圖片描述