我创建了一个带有 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,这使得很难创建另一个等待其输出的线程。
我希望我的解释能够解决问题:/
编辑:
这个想法是,我将计算不同文件中的单词数量,每个文件需要为自己分配一个线程以加快速度。除此之外,我希望一个线程等待所有其他线程的输出(这意味着我必须等待它们完成,因此我会感谢访问线程的名称)。
最后,一直在等待的最后一个线程将在关闭程序之前将收集到的数据用于自己的操作。
最佳答案
为了等待线程完成,您需要保存对您创建的线程的引用。例如,您可以这样做
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());
}
关于java - 递增线程名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27411856/