在我的前面的问题我贴:
我要读几个非常大的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个线程?
而用户使用的线程池建议:
当用户指定多少线程使用,你会适当地配置池,提交一套文件读取工作,并让池理清处决。 在Java世界中,你会使用Executors.newFixedThreadPool工厂方法,并提交各自的工作作为一个可赎回。 下面是IBM对Java线程池的文章。
所以现在我有我有一个名为sortAndMap(串x),其发生在一个txt文件名并执行的处理,并且对于上面的示例方法中,将具有
Executors.newFixedThreadPool(numThreads);
如何使用这个与线程池,这样我上面的例子是可行的?
好吧,承担与我在这,因为我需要解释一些事情。
首先,除非你有多个磁盘或者一个单盘是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
}
}
我会通过阅读这篇启动教程高级别的并发。 我建议你阅读整个并发教程 ,因为它听起来像是你是新的多线程。
因此, newFixedThreadPool()
调用将返回的实例ExecutorService的 。 您可以参考的JavaDoc,这是非常全面的,包含了一个可行的例子。 你会想要么submit
或invokeAll
一些Callable
小号实现文件处理任务,给你一些Future
的回报秒。 他们get()
方法会给您完成后,任务执行的结果(你必须自己写的那部分:))