Java中有一個BlockingQueue能夠用來充當堵塞隊列,下面是一個桌面搜索的設計java
package net.jcip.examples; import java.io.File; import java.io.FileFilter; import java.util.concurrent.*; /** * ProducerConsumer * <p/> * Producer and consumer tasks in a desktop search application * */ public class ProducerConsumer { static class FileCrawler implements Runnable { private final BlockingQueue<File> fileQueue; private final FileFilter fileFilter; private final File root; public FileCrawler(BlockingQueue<File> fileQueue, final FileFilter fileFilter, File root) { this.fileQueue = fileQueue; this.root = root; this.fileFilter = new FileFilter() { public boolean accept(File f) { return f.isDirectory() || fileFilter.accept(f); } }; } private boolean alreadyIndexed(File f) { return false; } public void run() { try { crawl(root); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } private void crawl(File root) throws InterruptedException { File[] entries = root.listFiles(fileFilter); if (entries != null) { for (File entry : entries) if (entry.isDirectory()) crawl(entry); else if (!alreadyIndexed(entry)) fileQueue.put(entry); } } } static class Indexer implements Runnable { private final BlockingQueue<File> queue; public Indexer(BlockingQueue<File> queue) { this.queue = queue; } public void run() { try { while (true) indexFile(queue.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public void indexFile(File file) { // Index the file... }; } private static final int BOUND = 10; private static final int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); public static void startIndexing(File[] roots) { BlockingQueue<File> queue = new LinkedBlockingQueue<File>(BOUND); FileFilter filter = new FileFilter() { public boolean accept(File file) { return true; } }; for (File root : roots) new Thread(new FileCrawler(queue, filter, root)).start(); for (int i = 0; i < N_CONSUMERS; i++) new Thread(new Indexer(queue)).start(); } }
多個文件爬取線程充當生產者,不斷的生產出數據來放到BlockingQueue中,而後由索引線程從BlockingQueue中獲得app
數據來解析文件。this