2016-08-02 36 views
0

我正在爲我的目的開發一個簡單的搜索工具。 我的意圖是搜索指定文件夾下的所有文件或特定文件。 我認爲與多個線程。 如果文件 不包含在列表中,則每個線程將開始搜索文件並將該文件放入列表中。 因此,每個線程不會掃描相同的文件。搜索具有多個線程的文件

我不確定這是否正確。 而當我運行程序時,我可以看到相同的結果,當我使用一個線程,兩個 甚至兩個以上。

然後我用了Executor服務,仍然得到相同的執行時間。我找不到 找不到。我的問題如下。

1.Am我使用正確的邏輯搜索多線程文件?

2.can當用一個線程,兩個線程等執行時,我能得到不同嗎?

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);  
    } 

} 
+2

似乎只有一個線程,是不是? –

+0

你只有一個'FileReaderRunnable'的實例,所以只有一個worker。嘗試創建它的幾個實例提供給'執行器' –

+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); 
    } 
}