5.生产者消费者Producer-consumer
避免生产和消费速率的差异,引入一个channel,对二者解耦
实现producer的时候用到了两阶段模式的AbstractTerminatedThread:
Channel.java
package comsumerproducer;
/**
* Channel
*/
public interface Channel<P> {
/**
* 取出一个产品
* @return
* @throws InterruptedException
*/
P take() throws InterruptedException;
/**
* 生产一个产品放入通道
* @param product
* @throws InterruptedException
*/
void put(P product) throws InterruptedException;
}
BlockingQueueChannel implements Channel
package comsumerproducer;
import java.util.concurrent.BlockingQueue;
/**
* 基于阻塞队列的通道实现
*/
public class BlockingQueueChannel<P> implements Channel<P> {
private final BlockingQueue<P> queue;
public BlockingQueueChannel(BlockingQueue<P> queue) {
this.queue = queue;
}
@Override
public P take() throws InterruptedException {
return queue.take();
}
@Override
public void put(P product) throws InterruptedException {
queue.put(product);
}
}
AttachmentProcessor 角色Producer
package comsumerproducer;
import twophased.AbstractTerminatedThread;
import java.io.*;
import java.text.Normalizer;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
/**
* 模式角色:producer
*/
public class AttachmentProcessor {
private final String ATTACHMENT_STORE_BASE_DIR =
"/home/viscent/tmp/attachments/";
/**
* 模式角色:Channel
*/
private final Channel<File> channel =
new BlockingQueueChannel<File>(new ArrayBlockingQueue<File>(200));
/**
* 模式角色:Consumer
*/
private final AbstractTerminatedThread indexingThread = new AbstractTerminatedThread() {
@Override
protected void doRun() throws Exception {
File file = null;
file = channel.take();
try {
indexFile(fi