问题描述
我正在使用 ThreadPoolExecutor 在我的 Java 应用程序中实现线程.
I am using the ThreadPoolExecutor to implement threading in my Java Application.
我有一个 XML,我需要解析它并将它的每个节点添加到线程以执行完成.我的实现是这样的:
I have a XML which I need to parse and add each node of it to a thread to execute the completion. My implementation is like this:
parse_tp 是创建的线程池对象 &ParseQuotesXML 是具有 run 方法的类.
parse_tp is a threadpool object created & ParseQuotesXML is the class with the run method.
try {
List children = root.getChildren();
Iterator iter = children.iterator();
//Parsing the XML
while(iter.hasNext()) {
Element child = (Element) iter.next();
ParseQuotesXML quote = new ParseQuotesXML(child, this);
parse_tp.execute(quote);
}
System.out.println("Print it after all the threads have completed");
catch(Exception ex) {
ex.printStackTrace();
}
finally {
System.out.println("Print it in the end.");
if(!parse_tp.isShutdown()) {
if(parse_tp.getActiveCount() == 0 && parse_tp.getQueue().size() == 0 ) {
parse_tp.shutdown();
} else {
try {
parse_tp.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
log.info("Exception while terminating the threadpool "+ex.getMessage());
ex.printStackTrace();
}
}
}
parse_tp.shutdown();
}
问题是,这两个打印输出语句是在其他线程退出之前打印出来的.我想让主线程等待所有其他线程完成.在普通的线程实现中,我可以使用 join() 函数来实现,但在 ThreadPool Executor 中无法实现相同的目标.还想问一下finally里写的代码块关闭线程池是否正确?
The problem is, the two print out statements are printed before the other threads exit. I want to make the main thread wait for all other threads to complete.In normal Thread implementation I can do it using join() function but not getting a way to achieve the same in ThreadPool Executor. Also would like to ask if the code written in finally block to close the threadpool proper ?
谢谢,阿米特
推荐答案
为了回答您的第二个问题,我认为您在尝试清理线程池方面做得很合理.
To answer your second question, I think you are doing a reasonable job trying to clean up your thread pool.
关于你的第一个问题,我认为你想使用的方法是 提交 而不是execute
.与其试图用文字解释这一切,不如用我编写的单元测试中的一个编辑片段来完成许多任务,让每个任务完成总工作的一个片段,然后在起点相遇以添加结果:
With respect to your first question, I think the method that you want to use is submit rather than execute
. Rather than try to explain it all in text, here's an edited fragment from a unit test that I wrote that makes many tasks, has each of them do a fragment of the total work and then meets back at the starting point to add the results:
final AtomicInteger messagesReceived = new AtomicInteger(0);
// ThreadedListenerAdapter is the class that I'm testing
// It's not germane to the question other than as a target for a thread pool.
final ThreadedListenerAdapter<Integer> adapter =
new ThreadedListenerAdapter<Integer>(listener);
int taskCount = 10;
List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
for (int whichTask = 0; whichTask < taskCount; whichTask++) {
FutureTask<Integer> futureTask =
new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// Does useful work that affects messagesSent
return messagesSent;
}
});
taskList.add(futureTask);
}
for (FutureTask<Integer> task : taskList) {
LocalExecutorService.getExecutorService().submit(task);
}
for (FutureTask<Integer> task : taskList) {
int result = 0;
try {
result = task.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException("ExecutionException in task " + task, ex);
}
assertEquals(maxMessages, result);
}
int messagesSent = taskCount * maxMessages;
assertEquals(messagesSent, messagesReceived.intValue());
我认为这个片段与您想要做的类似.关键组件是 提交 和 get 方法.
I think this fragment is similar to what you're trying to do. The key components were the submit and get methods.
这篇关于ThreadPoolExecutor如何让主线程等待其他线程完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!