Unhandled Exception
Unhandled Exception

Reputation: 1513

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 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.

Upvotes: 1

Views: 380

Answers (1)

Sofo Gial
Sofo Gial

Reputation: 703

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

Upvotes: 1

Related Questions