如何使用阻塞队列查询文件内容中的关键字
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核心技术》第八版14.6节使用阻塞队列的代码(生产者—消费者,根据关键字搜索文件内容)
- 基于Java阻塞队列实例(文件及文件内容搜索)
- 关于如何使用properties读取配置文件内容问题
- CoreJava_线程并发(阻塞队列):在某个文件夹下搜索含有某关键字的文件
- 关于如何使用vc6.0读取xml文件中的内容
- 如何使用Oracle的外部表查询警告日志文件
- 51.如何使用FileInputStream读取其他文件的内容
- 如何读取一个本地Json文件并查询该文件展示其内容
- 请教大家,如何使用sed命令,替换文件指定行的内容呢?-Linux系统管理-ChinaUnix.net
- ORACLE如何使用模糊查询(如何实现关键字搜索)
- 如何使用GDB显示不同C文件中的同名结构体内容
- [MOSS 译]如何:在WEB内容查询部件中使用自定义的字段
- 如何使用grep查询出不包含某匹配模式的文件
- 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma
- KB242450:如何使用关键字和查询词查询 Microsoft 知识库
- Linux学习笔记——如何使用echo指令向文件写入内容
- ubuntu12.04中如何查找文件中的内容含有某些关键字的文件夹/文件
- 使用PYTHON实现如何修改文本文件中的内容
- 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma
- 如何使用grep查询出不包含某匹配模式的文件