我制作了一个需要x个参数的函数。每个参数代表一个文件。
我希望为这些文件中的每一个分配一个线程,以便尽可能快地计算文件的单词。目前我已经做了一些似乎有用的事情,但是我发现自己在检查线程时遇到了麻烦,因为它们都被赋予了名称“t”
以某种方式增加线程的名称会很好。第一个线程将是t1,并将分配给第一个文件,依此类推。
for (File file : fileList) {
final File f = file;
Thread t = null;
ThreadGroup test = null;
Runnable r = new Runnable() {
public void run() {
Scanner fileScan;
try {
fileScan = new Scanner(f);
}
catch(FileNotFoundException e){
System.out.println("Something went wrong while accessing the file");
return;
}
int words = 0;
while (fileScan.hasNext()) {
words++;
fileScan.next();
}
System.out.println(f.getName() + ": " + words + " words");
System.out.println(Thread.activeCount() + ": ");
}
};
t = new Thread(r);
t.start();
}
在使用Thread.activeCount()进行检查时,线程数会上升,但我不知道如何联系它们,因为我已经为所有人分配了名称为t,这使得很难再创建另一个线程等待他们的输出。
我希望我的解释能够澄清这个问题:/
编辑:
我的想法是,我将计算不同文件中的单词数量,每个文件都需要为自己分配一个线程来加快速度。除此之外,我想要一个线程等待来自所有其他线程的输出(这意味着我将不得不等待它们完成,因此我为什么要访问线程的名称)。
最后,在关闭程序之前,等待的最后一个线程将使用收集的数据进行自己的操作。
答案 0 :(得分:1)
为了等待线程完成,您需要保存对您创建的线程的引用。你可以做一下
List<Thread> threads = new ArrayList<>();
然后在循环结束时执行threads.add(t);
。
之后你可以等待他们完成
for (Thread t : threads) {
t.join();
}
然而,有问题的是,你无法读取你已经开始的线程的结果。
更好的方法就是使用ExecutorService
和ThreadPoolExecutor
。这样您就可以提交Callable<Integer>
而不是Runnable
,并且您将能够获得字数的结果。
以下是帮助您入门的大纲:
ExecutorService service = Executors.newFixedThreadPool(numThreads);
List<Future<Integer>> results = new ArrayList<>();
for (File f : fileList) {
results.add(service.submit(new Callable<Integer>() {
// ...
}));
}
for (Future<Integer> result : results) {
System.out.println("Result: " + result.get());
}