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

时间:2018-01-11 04:32:51

标签: java multithreading threadpool runnable threadpoolexecutor

我目前正致力于多线程文档相似度计划。简单地说,程序的这个摘录得到一个对象,将它传递给一个" 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());

2 个答案:

答案 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>