使用Java中的线程实现生产者消费者问题。生产者和消费者共享缓冲区,生产者将元素放在缓冲区中,消费者使用共享缓冲区中的元素。如果缓冲区已满,则生产者应该等到消费者拿出元素,同样消费者应该等到生产者放入缓冲区为空的元素。 您的程序应接受以下输入:
m: the number of producer threads
n: the number of consumer threads
k: the size of the bounded buffer
您的代码应按该顺序提示输入上述输入。您可以假设用户为每个提供了一个有效的整数。您将需要生成m个Producer线程和n个Consumer线程。每个生成器生成20个整数,范围在0到9之间,并将它们放在缓冲区中。在缓冲区中放入一个数字后,它会打印其ID以及生成的数字。生产者在再次重复数字生成周期之前休眠一段随机时间。每个消费者从缓冲区中获取一个数字,然后打印其ID以及它获得的值。然后,它会在从缓冲区再次读取之前休眠一段随机时间。 该程序的示例输出是:
Producer #2 put: 1
Producer #1 put: 4
Consumer #3 got: 1
Producer #1 put: 3
Consumer #3 got: 4
Consumer #3 got: 3
...
我有这个问题。很明显,缓冲区数组是两个方法的全局变量,因为该数组与Producer&消费者。所以?不幸的是我不知道该怎么做这个项目。有谁有想法?
答案 0 :(得分:0)
import java.security.SecureRandom;
import java.util.concurrent.*;
/**
* Created by Leon.H on 2016/1/13.
*/
public class ProducerConsumer {
private int producerNumber = 0;
private int consumerNumber = 0;
private int bufferSize = 0;
private final int seconds;
public ProducerConsumer(int producerNumber, int consumerNumber, int bufferSize, int seconds) {
this.producerNumber = producerNumber;
this.consumerNumber = consumerNumber;
this.bufferSize = bufferSize;
this.seconds = seconds;
System.out.println(this.producerNumber+ ": the number of producer threads");
System.out.println(this.consumerNumber+ ": the number of consumer threads");
System.out.println(this.bufferSize+ ": the number of producer threads");
}
public void process() throws InterruptedException {
ExecutorService producerExecutorService = Executors.newFixedThreadPool(this.producerNumber);
ExecutorService consumerExecutorService = Executors.newFixedThreadPool(this.consumerNumber);
BlockingQueue<Integer> integers = new ArrayBlockingQueue<Integer>(this.bufferSize);
for (int i = 0; i < this.producerNumber; i++) {
producerExecutorService.execute(new ProducerTask(integers));
}
for (int i = 0; i < this.consumerNumber; i++) {
consumerExecutorService.execute(new ConsumerTask(integers));
}
producerExecutorService.shutdown();
consumerExecutorService.shutdown();
//let the program run 10 seconds
producerExecutorService.awaitTermination(this.seconds, TimeUnit.SECONDS);
consumerExecutorService.awaitTermination(this.seconds, TimeUnit.SECONDS);
}
private class ProducerTask implements Runnable {
private final BlockingQueue<Integer> integers;
public ProducerTask(BlockingQueue<Integer> integers) {
this.integers = integers;
}
public void run() {
while (true) {
Integer content = new SecureRandom().nextInt(1000);
System.out.println("Producer #" + Thread.currentThread().getId() + " put: " + content);
integers.offer(content);
try {
Thread.sleep(new SecureRandom().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class ConsumerTask implements Runnable {
private final BlockingQueue<Integer> integers;
public ConsumerTask(BlockingQueue<Integer> integers) {
this.integers = integers;
}
public void run() {
while (true) {
try {
System.out.println("Consumer #" + Thread.currentThread().getId() + " get: " + integers.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(new SecureRandom().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
import org.junit.Test;
/**
* Created by Leon.H on 2016/1/13.
*/
public class ProducerConsumerTest {
@Test
public void oneProducerOneConsumerSizeOne() throws InterruptedException {
int ProducerNumber = 1;
int ConsumerNumber = 1;
int size = 1;
int seconds=5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
@Test
public void twoProducerThreeConsumerSizeThree() throws InterruptedException {
int ProducerNumber = 2;
int ConsumerNumber = 3;
int size = 3;
int seconds = 5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
@Test
public void twoHundredProducerThreeConsumerSizeThree() throws InterruptedException {
int ProducerNumber = 20;
int ConsumerNumber = 3;
int size = 3;
int seconds=5;
ProducerConsumer producerConsumer = new ProducerConsumer(ProducerNumber, ConsumerNumber, size, seconds);
producerConsumer.process();
}
}