2012-07-19 39 views
1

我正在用Java 7併發和並行性功能 - 叉/聯接框架弄髒我的手。Java 7:叉/加入示例 - 我是否明白這一點?

我想顯示給定路徑下所有目錄的列表。有人能告訴我,如果我得到這個正確的?

這裏是我的主類 - JoinForkExample揭開序幕任務

package com.skilledmonster.examples; 

import java.io.File; 
import java.util.List; 
import java.util.concurrent.ForkJoinPool; 

public class JoinForkExample { 
    public static void main(String[] args) { 
     ForkJoinPool forkJoinPool = new ForkJoinPool() ; 
     List<File> directories = forkJoinPool.invoke(new DirectoryListingTask(new File("C:/xampp"))) ; 
     for (int i = 0; i < directories.size(); i++) { 
      File file = (File) directories.get(i); 
      System.out.println(file.getAbsolutePath()); 
     } 
    } 
} 

這裏是我的實際任務

package com.skilledmonster.examples; 

import java.io.File; 
import java.io.FileFilter; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.concurrent.RecursiveTask; 

public class DirectoryListingTask extends RecursiveTask<List<File>> { 

    private static final FileFilter filter = new DirectoryFilter(); 

    private File file ; 

    public DirectoryListingTask(File file) { 
     this.file = file; 
    } 

    @Override 
    protected List<File> compute() { 
     List<RecursiveTask<List<File>>> forks = new LinkedList<>(); 
     List files = new ArrayList(); 
     if (file.isDirectory()) { 
      File[] filteredFiles = file.listFiles(filter); 
      if (null != filteredFiles) { 
       files.addAll(Arrays.asList(filteredFiles)); 
      } 
      for (File childFile : file.listFiles()) { 
       DirectoryListingTask task = new DirectoryListingTask(childFile); 
       forks.add(task); 
       task.fork(); 
      } 

      for (RecursiveTask<List<File>> task : forks) { 
       files.addAll(task.join()); 
      } 
     } 
     return files ; 
    } 
} 

我幾乎得到預期的結果。但是我不確定我是否有這個權利。令人驚訝的是,即使我在不​​使用join/fork框架的情況下執行相同的操作,我也沒有注意到任何執行時間差異。

任何想法!

回答

3

由於這項工作主要是IO綁定的,因此在這裏使用Fork/Join並不是很有幫助。我會建議嘗試一些計算密集型任務。另外,請注意Fork/Join操作有開銷。如果你用它來計算斐波那契系列,它將不值得。我希望性能比順序版本慢。

+1

你是對的!我記得在一篇oracle技術網絡文檔中讀到,「ork/join任務應該像沒有I/O操作起作用的」純粹的「內存中算法一樣運行。」你能否建議我其他可以使用的實時示例? – jagamot 2012-07-19 04:30:55

+0

也許有些任務像quicksort。如果將它應用於非常大的問題,我們應該小心。在Fork/Join模式中,父母等待孩子在父母完成工作前完成工作。如果問題的嚴重程度足夠大,您會得到一個很大的任務隊列。這可能會導致像OutOfMemory這樣的問題。 – 2012-07-19 04:46:59

+2

嘗試MergeSort,它是一個遞歸算法。但是,由於每個遞歸步驟都將問題分解爲2個相等的平衡子問題,因此可以將它們分叉。 – giampaolo 2012-12-26 23:05:37