ScheduledThreadPoolExecutor threads remain when completed

问题: The routine myProcessToRun() needs to be executed 100 times but there needs to be about a second delay between each execution. The following FOR Loop is used in conjunct...

问题:

The routine myProcessToRun() needs to be executed 100 times but there needs to be about a second delay between each execution.

The following FOR Loop is used in conjunction with the ScheduledThreadPoolExecutor object.

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

This actually works fine but the threads still remain. Using JVisualVM the number of Threads increases by 100 threads when the routine is executed. When the routine finishes, the 100 threads still remain.

Clicking the "Perform GC" button doesn't clean them up so Java still believe they should exist.

How do these threads get cleaned up using an example like above?

---Edited---

I noticed the ScheduledThreadPoolExecutor was being instantiated within the Loop which was a terrible idea. After moving it outside the LOOP the threads created weren't so bad.

After attempting to implement the solution there was unexpected behavior.

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

With the modified code, it would immediate stop all the processes with the shutdown and nothing was executed. With the executor.shutdown(); commented out and just using the awaitTermination(), the program just hung and after a few minutes, all the processes kicked off at the same time without delay which resulted in errors.

I suspect my implementation was wrong.


回答1:

There are a number of ways that you can do this. You can view some of them here: https://www.baeldung.com/java-executor-wait-for-threads

My personal favorite is the CountDownLatch:

Next, let’s look at another approach to solving this problem – using a CountDownLatch to signal the completion of a task.

We can initialize it with a value that represents the number of times it can be decremented before all threads, that have called the await() method, are notified.

For example, if we need the current thread to wait for another N threads to finish their execution, we can initialize the latch using 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();
  • 发表于 2019-01-10 02:14
  • 阅读 ( 245 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除