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()
.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.