生产者消费者问题,java代码改进版

问题描述:

  生产者进行生产,将生产的产品放入缓冲区;消费者从缓冲区中取出产品进行消费;当缓冲区已经放满产品时,生产者应该暂停生产,等待缓冲区中腾出空间来存放生产出来的产品;当缓冲区为空时,消费者不可以从缓冲区取产品拿来消费,必须等待生产者生产过后才能从缓冲区中取出产品来消费。实现过程中用到了size和n两个变量,size表示缓冲区的大小,n表示当前缓冲区中产品的数目,这段代码实现了互斥访问临界变量,并且生产者不必待消费者消费完缓冲区中全部产品后才进行生产,同时消费者也不必等待生产者放满缓冲区后才进行消费,是对前一次代码的改进。

代码实现如下:

class Q
{
    String name;
    int num=0;
    int size=10;
}

class Producer implements Runnable
{
    Q q;
    Producer(Q q)
    {
        this.q = q;
        this.q.name="producer";
    }
    public void run()
    {
        while(true)
        {
            synchronized(q)
            {
                if(q.num<q.size)
                {
                        q.num++;
                        System.out.println("producer已生产第:"+q.num+"个产品!");
                        try {
                                                Thread.currentThread().sleep(100);
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                        q.notify();
                }
                else
                {
                        try {
                                System.out.println("producer stop!");
                                                q.wait();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                }
            }
        }
    }
}

class Consumer implements Runnable
{
    Q q;
    Consumer(Q q)
    {
        this.q = q;
        this.q.name="consumer";
    }
    public void run()
    {
        while(true)
        {
            synchronized(q)
            {
                if(q.num>0)
                {
                        System.out.println("consumer要消费第:"+q.num+"个产品!");
                        q.num--;
                        try {
                                                Thread.currentThread().sleep(100);
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                        q.notifyAll();
                }
                else
                {
                        try {
                                System.out.println("consumer stop!");
                                                q.wait();
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                }
            }
        }
    }
}

public class project
{
    public static void main(String[] args)
    {
        Q q = new Q();
        new Thread(new Producer(q)).start();
        new Thread(new Consumer(q)).start();
    }
}