zoukankan      html  css  js  c++  java
  • 采用多线程和生产者消费者模式来实现对于一个目录以及所有子目录下的文件内容的搜索,打印出包含指定关键字的行.

      利用ArrayBlockingQueue可以方便的实现生产者和消费者,所有消费者线程共用资源ArrayBlockingQueue对象,从而实现线程安全.生产者线程搜索当前目录及子目录,并且将相应的File对象添加到队列中,消费者线程对每个File对象进行关键字的查询,如果查到头,即停止查询.

      

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    
    /**
     * Created by Administrator on 2016/6/30.
     */
    public class BlockingQueueTest {
        public static void main(String[] args) {
            Scanner in=new Scanner(System.in);
            System.out.print("Enter base directory:");
            String directory=in.nextLine();
            System.out.println("Enter key world.");
            String keyworld=in.nextLine();
            final int FILE_QUEUE_SIZE=10;   //队列的容积
            final int SEARCH_THREADS=100;   //消费者线程数目,(进行高并发的查询)
            BlockingQueue<File>queue=new ArrayBlockingQueue<>(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,keyworld)).start();//开启消费者线程
            }
        }
    }
    class FileEnumerationTask implements Runnable{
        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 (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        private void enumerate(File startingDirectory) {
            File[] files=startingDirectory.listFiles();
            for(File file:files) {
                if(file.isDirectory()) {
                    enumerate(file);
                }
                else {
                    try {
                        queue.put(file);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    class SearchTask implements Runnable {
        private BlockingQueue<File> queue;
        private String keyworld;
    
        public SearchTask(BlockingQueue<File> queue, String keyworld) {
            this.queue = queue;
            this.keyworld = keyworld;
        }
    
        @Override
        public void run() {
            boolean done=false;
            while (!done) {
                try {
                    File file=queue.take();     //线程安全的操作,取得File对象
                    if(file==FileEnumerationTask.DUMMY) {
                        queue.put(file);
                        done=true;  //队列到头,不再查询
                    }
                    else
                        search(file);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void search(File file) {
            try {
                try(Scanner in=new Scanner(file)) {
                    int lineNumber=0;
                    while(in.hasNextLine()) {
                        lineNumber++;
                        String line=in.nextLine();
                        if(line.contains(keyworld)) {
                            System.out.printf("%s:%d:%s:%n",file.getPath(),lineNumber,line);
                        }
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    luogu1060开心的金明
    luogu1048采药
    uva1025城市里的间谍
    scoi刷题记录(2019/04/07)
    差分及树上差分的正确食用姿势(2019/2/21学习笔记)
    图论技巧(2019/1/28之一)
    考试反思(2019/1/26学习笔记)
    考试反思(2019/1/22)
    「一本通 5.2 例 5」皇宫看守
    「一本通 5.2 例 3」数字转换
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5631314.html
Copyright © 2011-2022 走看看