BlockingQueue阻塞队列实现消费者生产者模型
阻塞队列提供了可阻塞的put和take方法,以及支持定时的offer和poll方法。这一结构非常适合用于实现生产者——消费者这种设计模式。
示例:
下面给出的例子实现一个给定路径的桌面搜索的功能(扫描给定路径上的文件并建立索引)。
生产者
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.BlockingQueue;
public class FileCrawler implements Runnable {
private final BlockingQueue<File> fileQueue;
private final FileFilter fileFilter;
private final File root;
public FileCrawler(BlockingQueue<File> fileQueue, FileFilter fileFilter,
File root) {
super();
this.fileQueue = fileQueue;
this.fileFilter = fileFilter;
this.root = root;
}
@Override
public void run() {
try {
crawl(root);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private boolean alreadyIndexed(File file){
return fileQueue.contains(file);
}
private void crawl(File root) throws InterruptedException {
File[] entries = root.listFiles(fileFilter);
if (entries != null) {
for (File entry : entries) {
if (entry.isDirectory()) {
crawl(entry); // di gui directory
} else if (!alreadyIndexed(entry))
fileQueue.put(entry);
}
}
}
}
消费者
import java.io.File;
import java.util.concurrent.BlockingQueue;
public class Indexer implements Runnable{
private final BlockingQueue<File> queue;
public Indexer(BlockingQueue<File> queue){
this.queue = queue;
}
public void run(){
while(true){
try {
File take = queue.take();
System.out.println("Index has been made to file:"+take+"\n");//indexFile()
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
测试类
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Solution {
public static void main(String[] args) {
BlockingQueue<File> queue = new LinkedBlockingQueue();
FileFilter filter = new FileFilter() {
@Override
public boolean accept(File pathname) {
return true;
}
};
File root = new File("D:\\path");
// only one consumer and provider used in test
new Thread(new FileCrawler(queue, filter, root)).start();
new Thread(new Indexer(queue)).start();
}
}