2012-02-14 63 views
3

我做的应用程序。它搜索具有特殊扩展名的文件。我使用多线程:在每个目录(小任务)创建一个线程,这使得这样的工作:有多少线程最好使用? (java)

/** 
* Explore given directory. 
* @param dir - directory to explore. 
* @return snapshot of directory - FilesAndDirs object, 
* which encapsulates information about directory. 
*/ 
public final FilesAndDirs exploreDirectory(final File dir) { 
    final List<File> subDirectories = new ArrayList<File>(); 
    final List<File> files = new ArrayList<File>(); 
    if (dir.isDirectory()) { 
     final File[] children = dir.listFiles(); 
     if (children != null) { 
      for (File child : children) { 
       if (child.isFile() && !child.isHidden() 
         && checkExtension(child)) { 
        files.add(child); 
       } else { 
       if (child.isDirectory() && !child.isHidden()) { 
         subDirectories.add(child); 
        } 
       } 
      } 
     } 
    } 
    return new FilesAndDirs(files, subDirectories); 
} 

这种方法使定目录的快照,并returs像FilesAndDirs对象,holdes列表文件和结果列出subDirs。在另一个方法(getFiles())中,我有List文件 - 具有给定扩展名的文件 - 是搜索结果和第二个List目录 - 它包含探索方法的每个目录的子目录。
因此,每个线程探索目录,给定的扩展名的文件,他放在结果列表中,他放在子目录列表中的给定目录的子目录,然后将它添加到getFiles()方法的目录列表中。我使用固定线程池,但问题是我应该使用多少个线程来获得更好的性能? 我读过,如果任务不是IO密集型的,我应该使数量等于可用核心数量 Runtime.getRuntime()。availableProcessors()。 现在探索C:和D:目录的时间是41秒。但也许我应该使用更多的线程或使用一些“魔术”类import java.util.concurrent。 这里是getFiles()方法:getFiles() method

+3

但您的任务大量使用I/O。所以你可以增加线程数量到可用处理器/内核的数量,但是我甚至不确定这是高性能的,因为你花在CPU上的时间很少,而在I/O上花费很多时间。当你增加对I/O的访问时,你创建一个小的开销,因为需要订购更多的请求(因为它是在一个带有SSD的智能手机上,所以没有头移动的问题) – 2012-02-14 20:20:36

+1

你需要对它进行基准测试找出不同的设备。即使有很多CPU核心,I/O限制的东西也可能在大多数设备上产生相似的结果。 – David 2012-02-14 20:26:05

回答

4

从硬盘驱动器读取是连续的,所以此处的多线程效率不高。您的方法受到硬盘驱动器上I/O操作的限制。不在你的CPU上。