Java实现生产者-消费者模式
1. 什么是生产者-消费者模式
生产者-消费者模式主要三种对象:生产者、消费者、队列。有一些生产者,每个生产者会生产一些产品,将它们放到队列中。这些产品会被消费者从队列中取出使用。队列存在最大长度,当队列满时,生产者需要等待消费者消费后才能继续将生产的产品放入队列中,当队列为空时,消费者需要等待生产者将新的产品放入队列才能继续消费产品。
2. 准备工作
我们可以把每个生产者和消费者看成一个线程,并且假设队列实现了如下的接口
队列接口
public interface IBlockedQueue <T> {
void enqueue(T item, Function<Integer, Void> onSuccess) throws InterruptedException;
T dequeue(Function<Integer, Void> onSuccess) throws InterruptedException;
int getTotalProduced();
int getTotalConsumed();
}
其中onSuccess函数接受队列当前的长度为参数,并且会在enqueue或dequeue操作成功之后马上被执行。这个函数帮助我们更容易地观察程序的运行情况。
然后就可以定义生产者和消费者
生产者
public static class Producer extends Thread {
public int id;
public IBlockedQueue<Product> queue;
public Producer(int id, IBlockedQueue<Product> queue) {
super("Producer-" + id);
this.id = id;
this.queue = queue;
}
@Override
public void run() {
try{
for (int i = 0; i < 100; i++) {
sleep(PRODUCE_TIME);
queue.enqueue(new Product(id * 1000 + i), size -> {
System.out.printf("Queue now has %d items\n", size);
return null;
});
System.out.printf("Producer %d produced item %d\n", id, id * 1000 + i);
}
} catch (InterruptedException e) {
this.interrupt();
}
}
}
消费者
public static class Consumer extends Thread {
public int id;
public IBlockedQueue<Product> queue;
private boolean isDone = false;
public Consumer(int id, IBlockedQueue<Product> queue) {
super("Consumer-" + id);
this.id = id;
this.queue = queue;
}
@Override
public void run() {
try{
while(true) {
sleep(CONSUME_TIME);
Product p = queue.dequeue(size -> {
System.out.printf("Queue now has %d items\n", size);
return null;
});
if (p == null) {
// no more products
//这一行现在永远不会执行,之后会做相应改动
break;
}
System.out.printf("Consumer %d consumed item %d\n", id, p.id);
}
} cat