2016-08-02 5 views
0

나는 내 목적에 맞는 간단한 검색 도구를 개발 중입니다. 내 의도는 지정된 폴더 아래의 모든 파일 또는 특정 파일을 검색하는 것입니다. 여러 스레드와 관련 있다고 생각했습니다. 각 스레드는 파일 검색을 시작하고 그 파일 이 목록에 없으면 해당 파일을 목록에 넣습니다. 그래서 각 스레드는 동일한 파일을 검사하지 않습니다.다중 스레드 파일 검색

올바른 접근 방식인지 아닌지 잘 모르겠습니다. 그리고 프로그램을 실행할 때 하나의 스레드 인 두 개의 이상을 사용하는 경우에도 동일한 결과를 볼 수있었습니다.

그런 다음 Executor 서비스를 사용했지만 여전히 동일한 실행 시간을 얻었습니다. 차이점을 찾을 수 없습니다. 내 질문은 아래와 같습니다.

1.Am 여러 스레드로 파일을 검색하는 데 올바른 논리를 사용하고 있습니까?

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

} 
+2

그것은 하나 개의 스레드 만이 있다는 것입니다하지? –

+0

당신은'FileReaderRunnable' 인스턴스를 하나만 가지므로 작업자는 하나뿐입니다. 'executor '에게 제공 할 인스턴스를 거의 만들지 마십시오 –

+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); 
    } 
} 
관련 문제