阻塞队列的简单应用
在指定文件目录下的所有子文件中搜索包含指定关键词的位置
生产者主线程用来向阻塞队列中添加待搜索的文件
其他子线程用来在文件中搜索并打印输出结果
package BaseLearn.multithreadingTest.searchFileForKey;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
/*
* @date 2019/10/23 - 9:42
*/
public class SearchFile {
private static final int QUEUE_SIZE = 10;
private static final int MAX_SEARCH = 100;
private static ArrayBlockingQueue<File> deque = new ArrayBlockingQueue<>(QUEUE_SIZE);
private static final File LAST_TAG = new File("");
public static void main(String[] args){
String dir;
String key;
Scanner input = new Scanner(System.in);
System.out.println("请输入要搜索的文件夹");
dir = input.nextLine();
System.out.println("请输入要搜索的关键词");
key = input.nextLine();
/*
生产者
*/
Runnable putFile = () -> {
try {
enumerate(new File(dir));
deque.put(LAST_TAG);
} catch (InterruptedException e) {
System.out.println("被中断出错");
}
};
new Thread(putFile).start();
/*
子线程
*/
for (int i = 0; i < MAX_SEARCH; i++) {
Runnable runnable = () -> {
boolean done = false;
try {
while (!done) {
// System.out.println("搜索中");
File file = deque.take();
if (file == LAST_TAG) {
deque.put(file);
done = true;
} else {
search(file, key);
}
}
} catch (InterruptedException e) {
System.out.println("搜索被中断");
}
};
new Thread(runnable).start();
}
}
/**
* 添加所有非文件目录的文件到集合中
*/
public static void enumerate(File directory) throws InterruptedException {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
// System.out.println("添加文件中。。。");
if (file.isDirectory()) {
enumerate(file);
} else {
deque.put(file);
}
}
}
}
/**
* 根据关键词寻找
*/
public static void search(File file, String keyword) {
try {
Scanner in = new Scanner(file, "GBK");
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);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}