Java多線程10-生產者消費者問題

一、生產/消費者模型多線程

生產/消費者模型是一個典型的多線程問題,涉及到的對象包括「生產者」、「消費者」、「倉庫」和「產品」。它們之間的關係以下;
(01)生產者僅僅在倉庫未滿的時候生產,倉庫滿了則中止生產this

(02)消費者僅僅在倉庫有產品的時候才能消費,倉庫空則等待spa

(03)當消費者發現倉庫沒有產品的時候會通知生產者生產線程

(04)生產者在生產出可消費的產品時,應該通知等待的消費者去消費code

二、實現對象

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

運行結果:blog

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

五個線程都把本身想生產或者想消費的執行完畢ci

相關文章
相關標籤/搜索