2012-07-19 153 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