搜索具有多个线程的文件

时间:2016-08-02 10:19:34

标签: java multithreading

我正在为我的目的开发一个简单的搜索工具。 我的目的是搜索指定文件夹下的所有文件或特定文件。 我想过多线程。 每个线程将开始搜索文件,并将该文件放入该文件的列表中 列表中不包含。 因此每个线程都不会扫描同一个文件。

我不确定这是不是正确的做法。 当我运行程序时,当我使用一个线程,两个时,我可以看到相同的结果 甚至超过两个。

然后我使用了Executor服务,我仍然得到相同的执行时间。我不能 找到差异。我的问题如下。

1.我使用正确的逻辑来搜索多个线程的文件吗?

2.我可以在执行一个线程,两个线程等时获得差异吗?

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FileReaderRunnable implements Runnable {

    private List<File> fileList = new ArrayList<>();
    private File mfile;

    public boolean finished;
    public FileReaderRunnable(File file) {
        this.mfile = file;
    }

    @Override
    public void run() {
        //System.out.println("Thread current:"+Thread.currentThread().getName());
        //while(!finished){
            getfiles(mfile);
            //finished = false;
        //}

    }

    public void setFlag(boolean value) {
        finished = value;
    }

    public void getfiles(File file) {
        System.out.println("EXecuting...: "+Thread.currentThread().getName()+file.getAbsolutePath());
        File[] listFiles = file.listFiles();
        if (listFiles != null && listFiles.length > 0) {
            for (File file2 : listFiles) {
                if(!fileList.contains(file2.getAbsoluteFile())){
                    fileList.add(file2.getAbsoluteFile());  
                }               
                getfiles(file2);
            }
        }
    }

    public List<File> getFiles(){
        return fileList ;
    }

}

public class FileReaderThreadMain { 
    public static void main(String[] args) {        
        ExecutorService executor = Executors.newFixedThreadPool(30);
        File file = new File("C:\\Temp");
        FileReaderRunnable r = new FileReaderRunnable(file);
        long startTime = System.nanoTime();
        executor.execute(r);    
        executor.shutdown();
        // Wait until all threads are finish
        while (!executor.isTerminated()) { 
        }       
        long endTime = System.nanoTime();       
        System.out.println("\nFinished all threads");   
        System.out.println("main thread exited");       
        List<File> files = r.getFiles();
        System.out.println("Total Files size: "+files.size());      
        long duration = (endTime - startTime);
        System.out.println("Duration: "+duration/1000000 );     
    }

}

1 个答案:

答案 0 :(得分:0)

你可以这样做:

public class Test {

    private static final int THREAD_COUNT = 3;
    private static int taskDoneCount=0;
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
        List<String> allFiles = new ArrayList<>();
        File dir = new File("C:\\Temp");
        File[] files = dir.listFiles();
        int length = files.length;
        int onePart = length / THREAD_COUNT;
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < THREAD_COUNT; i++) {
            int startIndex = i * onePart; // the start index of the file list
            int endIndex = onePart * (i + 1);// the end index of the file list
            if (i == THREAD_COUNT-1) {
                endIndex = files.length;
            }
            System.out.println("Thread#"+(i+1)+" start index:"+startIndex+", end index:"+(endIndex-1));
            executor.execute(new SearchFileThread(startIndex, endIndex, files, fileList -> {
                synchronized (Test.class) {
                    taskDoneCount++;
                    allFiles.addAll(fileList);
                    if (taskDoneCount == THREAD_COUNT) {// check if all tasks finished
                        executor.shutdown(); // shutdown the thread pool
                        System.out.println("allFiles = " + allFiles);
                        System.out.println("allFiles.size() = " + allFiles.size());
                        System.out.println("Time used: "+(System.currentTimeMillis()-startTime)+"ms");
                    }
                }
            }));
        }
    }

    static private class SearchFileThread implements Runnable {
        private int startIndex;
        private int endIndex;
        private File[] listFiles;
        private List<String> fileList = new ArrayList<>();
        private TaskFinishListener listener;

        public SearchFileThread(int startIndex, int endIndex, File[] listFiles, TaskFinishListener listener) {
            this.startIndex = startIndex;
            this.endIndex = endIndex;
            this.listFiles = listFiles;
            this.listener = listener;
        }

        public void run() {
            for (int i = startIndex; i < endIndex; i++) {
                fileList.add(listFiles[i].getAbsolutePath());
            }
            listener.onFinish(fileList);
        }
    }

    private interface TaskFinishListener {
        void onFinish(List<String> fileList);
    }
}