Java多线程生产者消费者实例

Java基础

浏览数:34

2020-5-30

AD:资源代下载服务

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;
    }
}

厨师类:

/**
 * 厨师类
 * @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;
    }
}

测试类:两种食物,两个厨师,两个服务员,多个顾客,每个顾客点一种食物,每个服务员服务点专门的一种食物的顾客

/**
 * 测试类
 *
 */
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();
    }
}

程序写的不是很好,还有很多可以改进的地方,比如一个顾客可以点多种食物,一个服务员可以服务于任意一个顾客。这里的主要目的是实现生产者和消费者模式。

推荐一本Java多线程的书籍:《Java多线程编程核心技术》,这本书比较注重实践,对我理解Java的多线程有很大帮助。

作者:cicadaT