多线程——生产者消费者问题

Posted dch-21

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程——生产者消费者问题相关的知识,希望对你有一定的参考价值。

import java.util.LinkedList;
/**
 * @Author 昊
 * @Create 2020/5/2 9:34
 * @Description 临界资源,存放汉堡
 */
public class Box {
    //要进行频繁的删除操作所以使用LinkedList
    private LinkedList<Hamburger> list;
    //橱柜的容量
    private int capacity;

    public Box(){
        this(30);
    }

    public Box(int capacity){
        this.capacity=capacity;
        this.list=new LinkedList<>();
    }

    public LinkedList<Hamburger> getList() {
        return list;
    }

    //存入一个汉堡
    public synchronized void push(Hamburger hamburger){
        if(this.list.size()>=this.capacity) {
            try {
                //橱柜已满,生产者等待
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.list.add(hamburger);
        //唤醒消费者
        this.notifyAll();


//        if(this.list.size()<this.capacity) {
//            this.list.add(hamburger);
//        }else {
//            try {
//                //橱柜已满,生产者等待
//                this.wait();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            //唤醒消费者
//            this.notifyAll();
//        }

    }

    //取出一个汉堡
    public synchronized Hamburger pop(){
        if(this.list.size()==0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Hamburger hamburger=this.list.removeFirst();
        if(this.list.size()<5){
            //库存告急,唤醒生产者
            this.notifyAll();
        }
        return hamburger;
    }
}
/**
 * @Author 昊
 * @Create 2020/5/2 9:34
 * @Description   
 */
public class Hamburger {
    //汉堡编号
    private int id;
    //汉堡名称
    private String name;

    public Hamburger(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Hamburger{" +
                "id=" + id +
                ", name=‘" + name + ‘‘‘ +
                ‘}‘;
    }
}
/**
 * @Author 昊
 * @Create 2020/5/2 9:35
 * @Description  消费者
 */
public class Customer extends Thread{
    //消费者需要知道从哪个橱柜中获取汉堡
    private Box box;
    //模拟消费的时间
    private long timeMillions;
    public Customer(Box box,String name,long timeMillions) {
        super(name);
        this.timeMillions = timeMillions;
        this.box=box;
    }

    @Override
    public void run() {
        while(true){
            if(this.box.getList().size()==0){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Hamburger hamburger=this.box.pop();
            System.out.println(getName()+"取出了编号是"+hamburger.getId()+"的"+hamburger.getName());
            //取出汉堡
            try {
                //模拟消费时间
                Thread.sleep(timeMillions);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            hamburger=null;
        }
    }
}

import java.util.Random;

/**
 * @Author 昊
 * @Create 2020/5/2 9:35
 * @Description 生产者
 */
public class Producer extends  Thread{
    //生产者需要知道从哪个橱柜中获取汉堡
    private Box box;
    //模拟生产者的生产时间
    private long timeMillions;


    public Producer(Box box,String name,long timeMillions) {
        super(name);
        this.timeMillions = timeMillions;
        this.box=box;
    }

    @Override
    public void run() {
        String[] names = {"香辣鸡腿堡", "菠萝鸡腿堡", "劲脆鸡腿堡", "双层牛肉汉堡", "鳕鱼堡"};
        Random random = new Random();
        while(true){
            Hamburger hamburger = new Hamburger(random.nextInt(1000), names[random.nextInt(names.length)]);
            try {
                //模拟生产时间
                Thread.sleep(timeMillions);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //存入汉堡
            this.box.push(hamburger);
            System.out.println(getName()+"制作了编号是"+hamburger.getId()+"的"+hamburger.getName());
        }
    }
}


/**
 * @Author 昊
 * @Create 2020/5/2 9:36
 * @Description
 */
public class Program {
    public static void main(String[] args) {
        Box box=new Box();
        Producer p1=new Producer(box,"黄小厨",100);
        Producer p2=new Producer(box,"白小厨",120);
        Producer p3=new Producer(box,"蓝小厨",80);

        Customer c1=new Customer(box,"李雷",1000);
        Customer c2=new Customer(box,"韩梅梅",1200);
        Customer c3=new Customer(box,"Judy",1500);
        Customer c4=new Customer(box,"Lucy",1000);
        Customer c5=new Customer(box,"Poly",1000);

        p1.start();
        p2.start();
        p3.start();
        c1.start();
        c2.start();
        c3.start();
        c4.start();
        c5.start();
    }
}

以上是关于多线程——生产者消费者问题的主要内容,如果未能解决你的问题,请参考以下文章

13,多线程-生产者消费者问题2

Java多线程:生产者消费者模型

LINUX多线程(生产者消费者模型,POXIS信号量)

多线程:生产者/消费者模式

消费者生产者多线程冻结

综合运用: C++11 多线程下生产者消费者模型详解(转)