您的位置:首页 > 编程语言 > Java开发

如何使用阻塞队列查询文件内容中的关键字

2017-11-03 00:00 357 查看
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;

/**
* Created by Administrator on 2017/10/29 0029.
* @author WXP
* 使用阻塞队列两个显著的好处就是:多线程操作共同的队列时不需要额外的同步,
* 另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减少两边的处理速度差距。
*/
public class BlockingQueueTest {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Enter base directory path: ");
String directory = in.nextLine();
System.out.print("Enter search keyword: ");
String keyWord = in.nextLine();
final int FILE_QUEUE_SIZE=10;//阻塞队列大小
final int SEARCH_THREADS=10;//关键字搜索线程个数
//基于ArrayBlockingQueue的阻塞队列
BlockingQueue<File> queue = new ArrayBlockingQueue<File>(FILE_QUEUE_SIZE);
//只启动一个线程来搜索目录
FileEnumerationTask enumerator = new FileEnumerationTask(queue,new File(directory));
new Thread(enumerator).start();
//启动100个线程用来在文件中搜索指定的关键字
for (int i = 0; i < SEARCH_THREADS; i++) {
new Thread(new SearchTask(queue,keyWord)).start();
}
}

}
class FileEnumerationTask implements Runnable{
//DUMMY文件对象,放在阻塞队列最后,用来标示文件已被遍历完
public static File DUMMY = new File("");
private BlockingQueue<File> queue;
private File startingDirectory;
public FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {
this.queue = queue;
this.startingDirectory = startingDirectory;
}

@Override
public void run() {
try {
enumerate(startingDirectory);
queue.put(DUMMY);//执行到这里说明指定的目录下文件已被遍历完
}catch (Exception e){
e.printStackTrace();
}
}

//将指定目录下的所有文件File对象的放入阻塞队列中
public void enumerate(File directory)throws InterruptedException{
File[] files = directory.listFiles();
for (File file: files) {
if(file.isDirectory()){
enumerate(file);
}else{
//将元素放入队尾,如果队列满则阻塞
queue.put(file);
}
}
}
}

class SearchTask implements Runnable{
private BlockingQueue<File> queue;
private String keyWord;

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 (Exception e){
e.printStackTrace();
}
}
public  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();
}
}

注:仅供分享,内容参照其他学者
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java
相关文章推荐