Search code examples
javamultithreadingscheduledexecutorservice

How to schedule a task at fixed rate with a duration longer than the rate?


I'm trying to schedule a task that requires ~2.25 sec to be run every second.Thus I know 3 threads should be enough to handle the load. My code looks like this:

private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);
scheduler.scheduleAtFixedRate(new Streamer(), 0, 1000, TimeUnit.MILLISECONDS);

interestingly this behaves like scheduledAtFixedDelay with a delay of 0 (threads finish every ~2.25 sec).

I know, that scheduleAtFixedRate can be late if a thread runs late. But shouldn't giving the executor a larger threadpool solve this problem?

I could easily circumnvent the problem by coding 3 executors to start every 3 seconds, but that would make administration unnecessarily difficult.

Is there an easier solution to this problem?


Solution

  • You can use threadPool and scheduler to achieve this effect:

    1. Create a fixedThreadPool (or other that will fullfill your needs), let say with 4 threads - the number of threads should be based on the time single task consumes to execute and the rate at which the tasks are scheduled, basically numberOfThreads = avgExecTimeOfSingleTaks * frequency + someMargin;

    2. then create scheduler thread, that every second (or other desired period) will add a job to the fixedThreadPool queue, then the tasks can overlap.

    This way of solving the problem has additional adventage:

    If your tasks start to take longer than 2.25 sec, or you would like to execute them with greater frequency, then all you have to do is to add some threads to the threadPool, whereas using the other answer, you need to recalculate and reschedule everything. So this approch gives you clearer and easier to maintenance approach.