如何确保池中的任务在程序退出前完成?

How to ensure the tasks in the pool should get finish before the program exits?

我目前正在开发一个多线程文档相似性程序。简单地说,程序的这个摘录获取一个对象,将其传递给 "hasher" 方法,对该对象的值进行最小哈希并将其添加到要操作的列表中以测试相似性。

我的问题是主线程似乎前进到我操作列表的地方,而池中的线程仍在 运行宁和 minhashing 对象值,使用 println 我可以看到程序有运行 直到最后,但线程仍在 运行() 方法中执行。

如何保证池中的任务在程序运行前完成?

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());

尝试关闭执行程序服务并等待所有线程终止,然后再尝试处理您的结果。

<Submit work to thread pool>
..

executorService.shutdownNow();
executorService.awaitTermination();
..
<Process results from threads>

How can I ensure that the tasks in the pool have completed before the program advances?

用于启动有序关机,其中执行之前提交的任务,您需要在将任务提交给执行器后调用以下方法。因为,调用 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 秒完成所有任务。