Java多線程生產者消費者實例

Java生產者消費者實例編程

設計:涉及到的類有食物、廚師、服務員、顧客以及測試類。廚師負責生產食物,服務員服務於顧客,顧客負責點餐以及吃飯。安全

技術點:Java多線程,線程安全(synchronized),wait()/notify()線程之間通訊。多線程

食物類:測試

/**
 * @Author: liudq
 * @Description:食物類
 * @Date: create in 2017/11/4 17:28
 */
public class Food {
    private int num;    //食物的數量,這個爲公共資源,多個線程競爭
    private String name;   

    public Food(int num, String name) {
        this.num = num;
        this.name = name;
    }

    public synchronized boolean add(){
        if (!max()){
            num++;
            return true;
        }else {
            return false;
        }
    }

    public synchronized boolean sub(){
        if (!min()){
            num--;
            return true;
        }else {
            return false;
        }
    }

    public boolean max(){
        if (num >= 10){
            return true;
        }
        return false;
    }

    public boolean min(){
        if (num <= 0){
            return true;
        }
        return false;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

廚師類:this

/**
 * 廚師類
 * @Author: liudq
 * @Description:廚師生產食物
 * @Date: create in 2017/11/4 17:35
 */
public class Cook {
    private String name;
    private Food food;

    public Cook(String name, Food food) {
        this.name = name;
        this.food = food;
    }

    /**
     * 廚師生產食物
     */
    public void produce()  {
            while (true){
                try {
                    synchronized (food){
                        boolean isAdd = food.add();
                        if (!isAdd){
                            System.out.println(food.getName()+"已經到達最大值了,不能再生成了!數量爲:"+food.getNum());
                            food.wait();
                        }else {
                            System.out.println(food.getName()+"已經作好了,數量爲:"+food.getNum());
                            Thread.sleep(1000);
                            food.notifyAll();
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Food getFood() {
        return food;
    }

    public void setFood(Food food) {
        this.food = food;
    }
}

顧客類:線程

/**
 * @Author: liudq
 * @Description: 顧客類
 * @Date: create in 2017/11/4 17:43
 */
public class Customer {

    private int id; //顧客編號
    private Food food;  //顧客點的食物

    public Customer(int id, Food food) {
        this.id = id;
        this.food = food;
    }

    public void order(){
        System.out.println(id+"號顧客點了"+food.getName());
    }

    public void eat(){
        System.out.println(id+"號顧客正在吃"+food.getName());
    }


    public Food getFood() {
        return food;
    }

    public void setFood(Food food) {
        this.food = food;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

服務員類:設計

/**
 * @Author: liudq
 * @Description: 服務員
 * @Date: create in 2017/11/4 17:55
 */
public class Waiter {
    private List<Customer> customers;
    private Cook cook;
    private Food food;

    public Waiter(List<Customer> customers, Cook cook, Food food) {
        this.customers = customers;
        this.cook = cook;
        this.food = food;
    }

    public void server() {
        for (Customer customer : customers){
            synchronized (food){
                System.out.println("歡迎光臨!");
                System.out.println(customer.getId()+"號客人開始點餐");
                customer.order();
                if (customer.getFood().min()){
                    food.notifyAll();
                    try {
                        food.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(customer.getId()+"號客人的"+food.getName()+"好了!");
                customer.getFood().sub();
                customer.eat();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Food getFood() {
        return food;
    }

    public void setFood(Food food) {
        this.food = food;
    }

    public List<Customer> getCustomers() {
        return customers;
    }

    public void setCustomers(List<Customer> customers) {
        this.customers = customers;
    }

    public Cook getCook() {
        return cook;
    }

    public void setCook(Cook cook) {
        this.cook = cook;
    }
}

測試類:兩種食物,兩個廚師,兩個服務員,多個顧客,每一個顧客點一種食物,每一個服務員服務點專門的一種食物的顧客server

/**
 * 測試類
 *
 */
public class App 
{
    public static void main( String[] args ) {
        Food food1 = new Food(0,"包子");
        Food food2 = new Food(0,"饅頭");
        final Cook cook1 = new Cook("王師傅",food1);
        final Cook cook2 = new Cook("李師傅",food2);
        List<Customer> customers1 = new ArrayList<Customer>();
        List<Customer> customers2 = new ArrayList<Customer>();
        for (int i = 1; i <= 5; i++){
            Customer customer = new Customer(i,food1);
            customers1.add(customer);
        }
        for (int i = 6; i <= 10; i++){
            Customer customer = new Customer(i,food2);
            customers2.add(customer);
        }
        final Waiter waiter1 = new Waiter(customers1,cook1,food1);
        final Waiter waiter2 = new Waiter(customers2,cook2,food2);
        Thread thread1 = new Thread() {
            public void run() {
                cook1.produce();
            }
        };
        Thread thread2 = new Thread() {
            public void run() {
                cook2.produce();
            }
        };
        Thread thread3 = new Thread() {
            public void run() {
                waiter1.server();
            }
        };
        Thread thread4 = new Thread() {
            public void run() {
                waiter2.server();
            }
        };
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

運行結果

程序寫的不是很好,還有不少能夠改進的地方,好比一個顧客能夠點多種食物,一個服務員能夠服務於任意一個顧客。這裏的主要目的是實現生產者和消費者模式。ip

推薦一本Java多線程的書籍:《Java多線程編程核心技術》,這本書比較注重實踐,對我理解Java的多線程有很大幫助。資源

相關文章
相關標籤/搜索