生產者與消費者模型 wait() · notify() 方法的使用

模型說明:

Cooker生產食物, 把食物放到盤子中,如果盤子中沒有食物就繼續生產。
客戶消費食物,如果盤子中有食物就把食物喫掉。

Object的wait() notify() 方法使用說明:
其中wait方法必須在 Object的 synchronized塊中執行
這裏寫圖片描述

public void make(){
        if(d.isEmpty()){
            int index = ran.nextInt(foods.length);
            String f = foods[index];
            System.out.println(name + "製作了"+f);
            d.setFood(f);
            d.setEmpty(false);
            //不能依賴於sleep來控制線程
            /*try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
        }
    }

Cooker類

package produce;

import java.util.Random;

public class Cooker implements Runnable{
    private String name;
    private String[] foods;
    private Disk d;
    private static Random ran = new Random();

    public Cooker(String name, Disk d) {
        super();
        this.name = name;
        this.foods = new String[]{"大米","饅頭","包子","豆沙包","魚","牛肉"};
        this.d = d;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String[] getFoods() {
        return foods;
    }
    public void setFoods(String[] foods) {
        this.foods = foods;
    }
    public Disk getD() {
        return d;
    }
    public void setD(Disk d) {
        this.d = d;
    }

    public void make(){
        synchronized (d) {
            if(d.isEmpty()){
                int index = ran.nextInt(foods.length);
                String f = foods[index];
                System.out.println(name + "製作了"+f);
                d.setFood(f);
                d.setEmpty(false);
                d.notify();
                try {
                    d.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }else{
                try {
                    d.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void run() {
        for(int i=0; i<20; i++){
            make();
        }
        d.setEnd(true);
    }

}

Customer 類

package produce;

public class Customer implements Runnable{
    private String name;
    private Disk d;
    public Customer(String name, Disk d) {
        super();
        this.name = name;
        this.d = d;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Disk getD() {
        return d;
    }
    public void setD(Disk d) {
        this.d = d;
    }

    public void eat(){
        synchronized (d) {
            if(!d.isEmpty()){
                String food = d.getFood();
                System.out.println(name + "正在享用"+food);
                d.setEmpty(true);
                d.notify();
                try {
                    d.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }else{
                try {
                    d.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }
    @Override
    public void run() {
        while(true){
            if(d.isEnd()){
                break;
            }
            eat();
        }
    }
}

Disk 類

package produce;

public class Disk {
    private String food;
    private boolean empty;
    private boolean end;


    public Disk(boolean end) {
        super();
        this.end = end;
    }
    public String getFood() {
        return food;
    }
    public boolean isEnd() {
        return end;
    }
    public void setEnd(boolean end) {
        this.end = end;
    }
    public void setFood(String food) {
        this.food = food;
    }
    public boolean isEmpty() {
        return empty;
    }
    public void setEmpty(boolean empty) {
        this.empty = empty;
    }

}

Test 類

package produce;

public class Test {
    public static void main(String[] args) {
        Disk d = new Disk(false);
        d.setEmpty(true);
        Cooker co = new Cooker("劉大廚",d);
        Customer cu = new Customer("王小胖",d);

        new Thread(co).start();
        new Thread(cu).start();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章