import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter base directory (C:/Program Files/Java/jdk1.7.0/src):");
String directory = in.nextLine();
System.out.print("Enter keyword (java):");
String keyword = in.nextLine();
final int FILE_QUEUE_SIZE = 10;
final int SEARCH_THREADS = 100;
BlockingQueue<File> queue = new ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
FileEnumerationTask enumerator = new FileEnumerationTask(queue, new File(directory));
new Thread(enumerator).start();//起一个线程,用于将指定目录下的文件加入队列
for(int i=1; i<SEARCH_THREADS; i++) {
//起多个线程,用于从队列中取出文件,并寻找关键字
new Thread(new SearchTask(queue, keyword)).start();
}
}
}
class SearchTask implements Runnable {
public SearchTask(BlockingQueue<File> queue, String keyword) {
this.queue = queue;
this.keyword = keyword;
}
@Override
public void run() {
try {
boolean done = false;
while(!done) {
File file = queue.take();//从队列中移除并返回
//如果文件是最后一个
if(file == FileEnumerationTask.DUMMY) {
queue.put(file);
done = true;
} else {
search(file);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void search(File file) throws IOException {
Scanner in = new Scanner(new FileInputStream(file));
//寻找关键字,记录:路径,关键字在多少行,显示该行
int lineNumber = 0;
while(in.hasNextLine()) {
lineNumber++;
String line = in.nextLine();
if(line.contains(keyword)) {
System.out.printf("%s:%d:%s%n", file.getPath(), lineNumber, line);
}
}
in.close();
}
private BlockingQueue<File> queue;
private String keyword;
}
class FileEnumerationTask implements Runnable {
public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
this.queue = queue;
this.startingDirectory = startingDirectory;
}
@Override
public void run() {
try {
enumerate(startingDirectory);//枚举出该目录下的所有文件
queue.put(DUMMY);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
for(File file : files) {
if(file.isDirectory()) {
enumerate(file);
} else {
queue.put(file);//如果队列满了,则自动阻塞
}
}
}
public static File DUMMY = new File("");
private BlockingQueue<File> queue;
private File startingDirectory;
}