使用多少个线程更好?(Java)

3

我正在开发一款搜索特定扩展名文件的应用程序。我使用多线程技术:对于每个目录(小任务),我都会创建一个线程,线程执行以下工作:

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

这个方法创建给定目录的快照,返回一个FilesAndDirs对象的结果,它包含List文件和List子目录。在另一个方法(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,所以不存在磁头移动的问题)。 - Guillaume Polet
1
你需要在几个不同的设备上进行基准测试才能找出答案。对于那些受到I/O限制的程序,即使有很多CPU核心,它们在大多数设备上的结果可能会相对类似。 - David
1个回答

4

从硬盘读取是顺序的,所以在这里使用多线程不高效。您的方法受限于硬盘上的I/O操作,而不是您的CPU性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接