ScheduledThreadPoolExecutor线程在完成后仍然保留

时间:2019-01-08 14:02:25

标签: java multithreading

例程myProcessToRun()需要执行100次,但每次执行之间需要大约一秒钟的延迟。

以下FOR循环与ScheduledThreadPoolExecutor对象一起使用。

for (int n=0; n<100; n++)
{
    final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    executor.schedule(new Runnable() {
      @Override
      public void run() {
          myProcessToRun();
      }
    }, (n+2), TimeUnit.SECONDS);                            
}

这实际上工作正常,但线程仍然存在。 使用JVisualVM,在执行例程时,线程数将增加100个线程。例程完成后,仍保留100个线程。

单击“ Perform GC”按钮不会清除它们,因此Java仍然认为它们应该存在。

如何使用上面的示例清理这些线程?

---编辑---

我注意到ScheduledThreadPoolExecutor正在Loop中实例化,这是一个糟糕的主意。将其移出LOOP之后,创建的线程还不错。

尝试实施解决方案后,出现意外行为。

final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);               
for (int n=0; n<100; n++)
{
    //final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
    executor.schedule(new Runnable() {
      @Override
      public void run() {
          doAddNewCondSet();
      }
    }, (n+2), TimeUnit.SECONDS);                            
}
try 
{
    executor.shutdown();
    if (!executor.awaitTermination(400, TimeUnit.SECONDS))
        executor.shutdownNow();
} catch (InterruptedException e1) 
{
    e1.printStackTrace();
}

使用修改后的代码,它将立即因关闭而停止所有进程,并且不执行任何操作。 与executor.shutdown();注释掉并仅使用awaitTermination(),程序刚刚挂起,几分钟后,所有进程同时启动,而没有延迟,从而导致错误。

我怀疑自己的实现有误。

1 个答案:

答案 0 :(得分:1)

您可以通过多种方法来执行此操作。您可以在此处查看其中的一些: https://www.baeldung.com/java-executor-wait-for-threads

我个人最喜欢的是CountDownLatch:

  

接下来,让我们看看解决此问题的另一种方法-使用   CountDownLatch表示任务已完成。

     

我们可以用一个代表次数的值来初始化它   可以在调用await()的所有线程之前将其递减   方法,通知。

     

例如,如果我们需要当前线程等待另一个N   线程完成执行,我们可以使用   N:

ExecutorService WORKER_THREAD_POOL 
  = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
    WORKER_THREAD_POOL.submit(() -> {
        try {
            // ...
            latch.countDown();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    });
}

// wait for the latch to be decremented by the two remaining threads
latch.await();