英文:
Java wait for all threads to complete before printing some information
问题
我正在使用Java中的线程来读取文件并将特定项目打印到控制台。我在循环中读取超过5个文件,循环结束时我想要打印一条消息。
所以:
for (int i = 1; i < args.length; i++){
String filename = args[i]; // 这将包含每个文件名
// 你的代码放在这里
new processFile(filename, counter).start();
}
System.out.print(counter.numberOfMatches);
我在网上寻找了解决方案,但几乎所有的建议都是使用join()
。这是否不违背了使用线程的目的?难道没有一种方法可以并行运行所有的文件处理线程,而不必让一个线程等待另一个线程,然后在所有进程都完成后再转到最后一行吗?
英文:
I am using threads in java to read file and print certain items to console. I am reading more than 5 files in a loop, and at the end of the loop I want to print a message.
So:
for (int i = 1; i < args.length; i++){
String filename = args[i]; //this will contain each filename
// your code goes here
new processFile(filename,counter).start();
}
System.out.print(counter.numerOfMatches)
I looked for solution online but almost all suggests using join(). Does that not defeat the purpose of using threads. Is there not a way to run all of the fileProcessing threads parallelly without one having to wait for the another and then somehow figure out when all of the processes finishes before moving to the final line?
答案1
得分: 2
使用 CountDownLatch:将其初始化为线程数,然后每个线程在完成时都会倒数计数器。主线程等待计数器。
类似这样的代码:
CountDownLatch latch = new CountDownLatch(args.length);
for (int i = 1; i < args.length; i++){
String filename = args[i];
new processFile(latch, filename, counter).start();
}
latch.await();
System.out.print(counter.numerOfMatches)
每个线程都需要在构造函数中传递计数器,以便看到计数器。线程完成工作后,通知/倒数计数器。
@Override
public void run() {
// 完成实际工作,然后通知我们已完成:
latch.countDown();
}
英文:
Use a CountDownLatch: initialize it with the number of threads, then have each thread count down the latch when it's done. The main thread awaits the latch.
Something like this:
CountDownLatch latch = new CountDownLatch(args.length);
for (int i = 1; i < args.length; i++){
String filename = args[i];
new processFile(latch, filename, counter).start();
}
latch.await();
System.out.print(counter.numerOfMatches)
Each of your threads needs to see the latch, for example by passing it in the constructor. When the thread is done, it notifies / counts down the latch.
@Override
public void run() {
// do actual work, then signal we're done:
latch.countDown();
}
答案2
得分: 1
join()的作用是确保在继续执行之前,您必须等待所有线程完成其工作的任务。如果您只想在所有线程完成某个任务后打印一条消息,并且希望能够继续处理已经完成的线程,您就不需要使用join()。例如,您可以启动某种计数器(信号量)类,每次线程完成时递增1,当达到您设定的线程数量时,它将打印您的消息。只需将打印操作作为添加函数的一部分即可。
英文:
join() is meant precisely for tasks for which you must wait for all the threads to finish their work in order to continue. If all you want to do is print a message when all the threads finish some task and be able to move on with the threads that already finished you don't need join(). You can, for example, start some kind of a Counter (Semaphore) class, increment 1 every time a thread finishes, and when it reaches the number of threads you had it will print your message. Simply make the print a part of the addition function.
答案3
得分: 1
你绝对可以使用ExecutorService
与newFixedThreadPool
,它将异步运行以处理每个任务。
ExecutorService executors = Executors.newFixedThreadPool(<<Number_of_Threads>>);
CompletionService<String> completionService = new ExecutorCompletionService<>(executors);
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < inp; i++) {
futures.add(completionService.submit(new WorkerThread("ThreadName-" + i)));
}
英文:
You can definitely use ExecutorService with newFixedThreadPool which will run asynchronously to process each task.
ExecutorService executors = Executors.newFixedThreadPool (<<Number_of_Threads>>);
CompletionService<String> completionService = new ExecutorCompletionService<>(executors);
List<Future<String>> futures = new ArrayList<> ( );
for (int i=0; i<inp; i++) {
futures.add ( completionService.submit ( new WorkerThread ("ThreadName-"+i) ));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论