1

I am trying an example using the method scheduleAtFixedRate of the class ScheduledExecutorService. The code is:

ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
        IntStream.range(0, 4).forEach(i -> service.scheduleAtFixedRate(() -> {try {
            System.out.println(i + " task completed!");
        } catch (Exception e) {
            e.printStackTrace();
        }}, 
                0, 3, TimeUnit.SECONDS));
        service.shutdown();

The output is:

1 task completed!
2 task completed!
0 task completed!

Why are not all 4 tasks executed?

If I omit the service.shutdown(); then all the tasks are executed and repeatedly as well, but it leads to memory leak. According to the docs any before shutdown registered task should be executed.

Moreover, if I pause the current Thread for a while using Thread.sleep(), then the output contains all the tasks as:

ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
        IntStream.range(0, 4).forEach(i -> service.scheduleAtFixedRate(() -> {try {
            System.out.println(i + " task completed!");
        } catch (Exception e) {
            e.printStackTrace();
        }}, 
                0, 3, TimeUnit.SECONDS));

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        service.shutdown();

Output:

0 task completed!
3 task completed!
2 task completed!
1 task completed! 

Is this the expected behavior of the method scheduleAtFixedRate?

Update:

When I use submit instead of scheduleAtFixedRate without delay then the behavior comes close to the expected. Calling shutdown() allows all 4 tasks to complete while shutdownNow() only 3:

ScheduledExecutorService service = Executors.newScheduledThreadPool(4);
        IntStream.range(0, 4).forEach(i -> service.submit(() -> {

        System.out.println(i + " task completed");}));

        service.shutdown();

If I refrain from ScheduledExcecutorService and use ExecutorService instead as:

ExecutorService service = Executors.newFixedThreadPool(4);
    IntStream.range(0, 4).forEach(i -> service.submit(() -> {

    System.out.println(i + " task completed");}));

     service.shutdown();

then all 4 tasks are always completed whether I use shutdown() of shutdownNow().

It seems that the ScheduledExecutorService behaves a little bit different on the task submission and perhaps on shutdown() and shutdownNow().

arjacsoh
  • 8,932
  • 28
  • 106
  • 166
  • It's not startling that some of the tasks don't get executed (you shutdown the pool prior to them starting), but I don't understand why don't all futures that haven't run yet (those that have just don't get rescheduled) -- why don't those futures get cancelled (I tried to hook there and only some get cancelled). – starikoff Oct 03 '16 at 13:48

1 Answers1

-1

Found this in the documentation of ExecutorService.class

This method does not wait for previously submitted tasks to complete execution. Use {@link #awaitTermination awaitTermination} to do that.

Check this Link for more info. From my PC I found out that sometimes all four threads complete execution. It depends on the time when shudown is called. Use awaitTermination method if you want to wait for your threads to complete.

When you made your main thread to sleep, it took time to execute shutdown and until then all the tasks were over.

Community
  • 1
  • 1
Pallav Jha
  • 3,409
  • 3
  • 29
  • 52