I have a main method that uses a ScheduledExecutorService with a core pool size of 75 to schedule running of 15 actions each for a total of 50,000 users:
Lists.partition(users, 100).stream()
.forEach(batchOfUsers -> batchOfUsers
.parallelStream().forEach(scheduleKickingOffActions));
scheduleKickingOffActions
has the user call scheduledExecutor.schedule(Runnable, delay)
15 times with different runnable actions and arbitrary delays.
This is a fairly heavy program, with a lot going on. As the main thread progresses with the batches, the schedules start kicking in and performing the actions. When each scheduled action kicks off, it reschedules itself with another arbitrary delay. So, each user runs each of his actions repeatedly.
Looking at the logging statements inside of scheduleKickingOffActions
, I notice that the main thread responsible for running the above code snippet stops at some point while scheduling these users' activities. The point ranges from the 4000th user to the 40000th. It seemingly 'forgets' to finish its task.
I don't have a good explanation for why this would happen, I can only imagine that as the scheduled tasks in the ScheduledExecutorService kick off, they manage to preempt the main thread..
I have further evidence for my main thread completely crapping out. After the batching code, I have a sleep statement:
Thread.sleep(360);
following which I do a:
scheduledExecutor.shutdownNow();
scheduledExecutor.awaitTermination(1, TimeUnit.HOURS);
System.out.println("\nFinished.\n");
stopwatch.stop();
System.out.println("Total time elapsed - " + stopwatch.elapsed(TimeUnit.SECONDS) + " seconds");
System.exit(0);
to enforce the program to run for 6 hours. None of these statements print, and my program keeps running beyond the 6-hour mark until I Ctrl+C out of it. Apparently, the main thread gets thrown off at some point during the batching job and never progresses further.
I don't see any exceptions in the output nor the logs, and the scheduled tasks all work as expected, and all get rescheduled as expected.
Would someone with more Java expertise care to share their thoughts on this? Is it a case of just too many threads working at the same time? I would expect the main thread to return to its task at some point.