生产者消费者最优解
optimal solution for 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 的 ArrayBlockingQueue 而不是 ArrayList
:
ArrayBlockingQueue<Employee> empList = new ArrayBlockingQueue<Employee>(1);
ArrayBlockingQueue
class 提供了两个阻塞调用,即 put and take。通过使用这些方法,您可以摆脱当前通过 wait
和 notify
进行的任何显式线程通信。执行此操作的理想方法是在 Producer
线程中调用 put
方法,在 while
循环中调用 Consumer
线程中的 take
方法。
由于队列的初始化大小为 1,因此在 while 循环中调用 put
时,任何试图在队列已满时向其插入新元素的线程都会等待。类似地,任何试图在队列为空时从队列中获取元素的线程都必须在 while 循环中调用 take
时等待。
我已经为生产者消费者问题编写了代码。下面是代码
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 的 ArrayBlockingQueue 而不是 ArrayList
:
ArrayBlockingQueue<Employee> empList = new ArrayBlockingQueue<Employee>(1);
ArrayBlockingQueue
class 提供了两个阻塞调用,即 put and take。通过使用这些方法,您可以摆脱当前通过 wait
和 notify
进行的任何显式线程通信。执行此操作的理想方法是在 Producer
线程中调用 put
方法,在 while
循环中调用 Consumer
线程中的 take
方法。
由于队列的初始化大小为 1,因此在 while 循环中调用 put
时,任何试图在队列已满时向其插入新元素的线程都会等待。类似地,任何试图在队列为空时从队列中获取元素的线程都必须在 while 循环中调用 take
时等待。