- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
关于我之前发布的一个问题:
我必须读取几个非常大的 txt 文件,并且必须使用多线程或单线程来完成,具体取决于用户输入。假设我有一个获取用户输入的主要方法,用户请求一个线程并希望为该线程处理 20 个 txt 文件。我将如何做到这一点?请注意,以下不是我的代码或其设置,而只是“想法”。
例子:
int numFiles = 20;
int threads = 1;
String[] list = new String[20];
for(int i = 1; i < 21; i++){
list[i] = "hello" + i + ".txt";//so the list is a hello1.txt, hello2.txt, ..., hello20.txt
}
public void run(){
//processes txt file
}
总而言之,我将如何使用单个线程完成此操作?有 20 个线程?
一位用户建议使用 threadPools:
当用户指定要使用的线程数时,您将适本地配置池,提交一组文件读取作业,然后让池对执行进行排序。在 Java 世界中,您将使用 Executors.newFixedThreadPool 工厂方法,并将每个作业作为 Callable 提交。这是 IBM 关于 Java 线程池的文章。
所以现在我有了一个名为 sortAndMap(String x) 的方法,它接受一个 txt 文件名并进行处理,对于上面的例子,将有
Executors.newFixedThreadPool(numThreads);
如何将它与 threadPools 一起使用,以便我上面的示例可行?
最佳答案
好的,请耐心等待,因为我需要解释一些事情。
首先,除非你有多个磁盘或者可能是一个 SSD 磁盘,否则不建议使用多个线程从磁盘读取。许多关于这个主题的问题已经发布,结论是相同的:使用多个线程从单个机械磁盘读取会损害性能而不是提高性能。
出现上述情况是因为磁盘的机械磁头需要不断寻找下一个要读取的位置。使用多线程意味着当每个线程都有机会运行时,它会将磁头指向磁盘的不同部分,从而使其在磁盘区域之间低效地反弹。
处理多个文件的公认解决方案是拥有一个生产者(读取线程)-多个消费者(处理线程)系统。在这种情况下,理想的机制是线程池,线程充当生产者并将任务放入池队列中以供工作人员处理。
像这样:
int numFiles = 20;
int threads = 4;
ExecutorService exec = Executors.newFixedThreadPool(threads);
for(int i = 0; i < numFiles; i++){
String[] fileContents = // read current file;
exec.submit(new ThreadTask(fileContents));
}
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
...
class ThreadTask implements Runnable {
private String[] fileContents;
public ThreadTask(String[] fileContents) {
this.fileContents = fileContents;
}
public void run(){
//processes txt file
}
}
关于java - 使用线程池/线程来读取大文本文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10397075/
我是一名优秀的程序员,十分优秀!