Java多线程10-生产者消费者问题

1、生产/消费者模型

生产/消费者模型是一个典型的多线程问题,涉及到的对象包括“生产者”、“消费者”、“仓库”和“产品”。它们之间的关系如下;
(01)生产者仅仅在仓库未满的时候生产,仓库满了则停止生产

(02)消费者仅仅在仓库有产品的时候才能消费,仓库空则等待

(03)当消费者发现仓库没有产品的时候会通知生产者生产

(04)生产者在生产出可消费的产品时,应该通知等待的消费者去消费

2、实现

class Depot
{
    private int capacity; //仓库容量
    private int size; //仓库的实际数量

    public Depot(int capacity)
    {
        this.capacity = capacity;
        this.size = 0;
    }

    public synchronized void produce(int val)
    {
        try
        {
            int left = val; //表示想要生产的数量
            while(left > 0)
            {
                while(size >= capacity) //仓库满了,等待消费者
                    wait();

                //计算实际增量
                //如果库存+想要生产的数量 > 容量,则“实际增量” = “容量” - “当前容量”(这样会填满仓库)
                //否则,增量 = 想要生产的数量
                int increment = (size+left) > capacity ? (capacity-size) : left;
                size = size + increment;
                left = left - increment;
                System.out.printf("%S produce(%d) --> left = %d,inc = %d, size = %d\n",
                        Thread.currentThread().getName(),val,left,increment,size);

                notifyAll();
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public synchronized void consume(int val)
    {
        try
        {
            int left = val;
            while(left > 0)
            {
                while(size <= 0)
                    wait();

                int decrement = size < left ? size : left;
                size = size - decrement;
                left = left - decrement;
                System.out.printf("%s consume(%d) <-- left = %d, dec = %d, size = %d\n",
                        Thread.currentThread().getName(),val,left,decrement,size);
                notifyAll();
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public String toString()
    {
        return "capacity:"+capacity+", actual size:"+size;
    }
}
class Customer
{
    private Depot depot;

    public Customer(Depot depot)
    {
        this.depot = depot;
    }

    public void consume(final int val)
    {
        new Thread()
        {
            public void run()
            {
                depot.consume(val);
            }
        }.start();
    }
}

class Producer
{
    private Depot depot;

    public Producer(Depot depot)
    {
        this.depot = depot;
    }

    public void produce(final int val)
    {
        new Thread()
        {
            public void run()
            {
                depot.produce(val);
            }
        }.start();
    }
}

public class Demo
{
    public static void main(String[] args)
    {
        Depot mDepot = new Depot(100);
        Producer mPro = new Producer(mDepot);
        Customer mCus = new Customer(mDepot);

        mPro.produce(60);;
        mPro.produce(120);
        mCus.consume(90);
        mCus.consume(150);
        mPro.produce(110);
    }
}

运行结果:

THREAD-0 produce(60) --> left = 0,inc = 60, size = 60
THREAD-4 produce(110) --> left = 70,inc = 40, size = 100
Thread-3 consume(150) <-- left = 50, dec = 100, size = 0
THREAD-1 produce(120) --> left = 20,inc = 100, size = 100
Thread-2 consume(90) <-- left = 0, dec = 90, size = 10
Thread-3 consume(150) <-- left = 40, dec = 10, size = 0
THREAD-4 produce(110) --> left = 0,inc = 70, size = 70
Thread-3 consume(150) <-- left = 0, dec = 40, size = 30
THREAD-1 produce(120) --> left = 0,inc = 20, size = 50

五个线程都把自己想生产或者想消费的执行完毕

posted @ 2020-05-04 00:48  qumasha  阅读(129)  评论(0编辑  收藏  举报