生产者消费者的最佳解决方

时间:2015-05-06 16:00:47

标签: java producer-consumer

我已经为生产者消费者问题编写了代码。以下是代码

package sample;

import java.util.List;
import java.util.ArrayList;

public class Interview2 {

    public static void main(String[] args) {

        List<Employee> empList = new ArrayList<Employee>();
        Thread producer = new Thread(new Producer(empList , 4) , "Producer");
        Thread consumer = new Thread(new Consumer(empList , 4) , "Consumer");

        producer.start();
        consumer.start();
    }

}

class Employee 
{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
class Producer implements Runnable 
{
    List<Employee> empList; 
    int size;

    public Producer(final List<Employee> empList  , final int size)
    {
        this.empList = empList;
        this.size = size;
    }

    public void run() {
        for(int i=0; i<7;i++)
        {
            System.out.println("Produced "+i);
            try {
                produce(new Employee());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }

public void produce(Employee e) throws InterruptedException
{
    while(empList.size()==size) // If list is full then will have to wait
    {
        synchronized(empList)
        {
            System.out.println("List is full "+Thread.currentThread().getName()+" Is waiting and" + " Size is "+empList.size());
            empList.wait();
        }
    }

    synchronized(empList)
    {
        empList.add(e);
        empList.notify();
    }
}


}


class Consumer implements Runnable 
{
    List<Employee> empList; 
    int size;

    public Consumer(final List<Employee> empList  , final int size)
    {
        this.empList = empList;
        this.size = size;
    }

    public void run()
    {
        while(true)
        {
            try {
                System.out.println("Consumed ");
                Thread.sleep(50);
                consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void consume() throws InterruptedException
    {
        while(empList.isEmpty()) // If list is empty then will have to wait
        {
            synchronized(empList)
            {
                System.out.println("List is empty "+Thread.currentThread().getName()+" Is waiting and " + "Size is "+empList.size());
                empList.wait();
            }
        }

        synchronized(empList)
        {
            empList.remove(0);
            empList.notifyAll();
        }

    }

}

但是我希望这个代码就像生产者在消费者消费之后在列表中添加一个雇员意味着必须在生产者和消费者之间切换。我想为10个对象重复它。请帮我修改代码。提前致谢

1 个答案:

答案 0 :(得分:1)

由于这看起来像某种任务,我会指出你正确的方向,而不是提供代码本身:

您可以使用尺寸为1的ArrayBlockingQueue代替ArrayList

ArrayBlockingQueue<Employee> empList = new ArrayBlockingQueue<Employee>(1);

ArrayBlockingQueue类提供了两个阻止调用,即puttake。通过使用这些方法,您可以通过waitnotify删除当前正在进行的任何显式线程通信。执行此操作的理想方法是在put线程中调用Producer方法,在take循环中调用Consumer线程中的while方法。

由于队列初始化的大小为1,因此任何尝试在队列中填充新元素的线程都会在while循环中调用put时等待。类似地,任何尝试从队列中获取元素的线程都是空的,在while循环中调用take时必须等待。