我目前正致力于多线程文档相似度计划。简单地说,程序的这个摘录得到一个对象,将它传递给一个" hasher"方法,对对象的值进行minhashes并将其添加到要操作的列表中以测试相似性。
我的问题是主线程似乎进入我操作列表的位置,而池中的线程仍在运行并且使用println运行对象值,我可以看到程序已经运行直到结束但是线程仍然在run()方法之后执行。
如何在程序前进之前确保池中的任务完成?
int docCount = 2;
while (docCount > 0) {
try {
Shingle s = q.take();
if (s instanceof Poisin == false) {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println("DEBUG : currently in run()" + Thread.currentThread());
if (s.getDocumentId() == 1) {
list1.add(hasher(s));
} else if (s.getDocumentId() == 2) {
list2.add(hasher(s));
} else {
voidList.add(hasher(s));
}
}
});// Runnable
} else {
docCount--;
}
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("INteruppted exception " + e);
}
}
float k1 = list1.size();
float k2 = list2.size();
System.out.println("DEBUG : End of program" + Thread.currentThread());
答案 0 :(得分:3)
如何确保池中的任务在之前完成 程序进展?
用于启动先前提交的任务执行的有序关闭,您需要在向执行程序提交任务后调用以下方法。因为,之后调用shutdown
将拒绝任何新任务。
pool.shutdown();
然后
pool.awaitTermination(60, TimeUnit.SECONDS) // specify timeout here
在Oracle documentation页面上,有一个示例(已复制):
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
上面,方法将确保,没有提交任何新任务,并将等待最多60
秒完成所有任务。
答案 1 :(得分:1)
尝试关闭执行程序服务并等待所有线程终止,然后再尝试处理结果。
<Submit work to thread pool>
..
executorService.shutdownNow();
executorService.awaitTermination();
..
<Process results from threads>