简体   繁体   中英

Scheduling algorithm used in Java ScheduledExecutorService

I am using ScheduledExecutorService for scheduling multiple java jobs. I wanted to know what happen in the following scenario:

If I am using,

ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

for scheduling 5 jobs with a thread pool size of one

p1 - 5(execution interval in minutes)

p2 - 5

p3 - 5

p4 - 7

p5 - 10

After 5 minutes p1, p2, and p3 would be active for contention.

What algorithm would be used for assigning the job to the one available thread ? Would they be assigned in round robin fashion?

Now at 7th minute, say p1 and p2 complete and p4 becomes active, but p3 is memory intensive and ends up using entire memory, then I assume that the scheduler itself would not get scheduled due to lack of memory. Is there any way to ensure that some memory is reserved for the scheduler?

ScheduledExecutorService is an interface and it does not define any of the things you are asking about.

So the answer depends on the concrete implementation you are using. If you use Executors.newScheduledThreadPool then you are effectively using a ScheduledThreadPoolExecutor . The javadoc says:

Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.

I'm not sure I understand your second question regarding memory - either you have enough memory or you don't. And if you don't you will get an OutOfMemoryError.

There will be no contention between tasks after 5 minutes.

Tasks are passed into queue and if there are no available threads to execute them, they will be executed in FIFO order, at least given the ScheduledThreadPoolExecutor implementation.

Note that your pending tasks may get 'silently' canceled if you have an exception which is not handled.

ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

If any execution of the task encounters an exception , subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late , but will not concurrently execute.

Memory is already 'reserved' for the scheduler instance, and if tasks use up all remaining memory JVM will not give them piece from the scheduler. This can and will result with OutOfMemoryError .

Edit

If there is only one thread in the pool, tasks p2 and p3 will be scheduled but they will not be executed until there is available thread.

Take a look at the code sample bellow:

private static final ScheduledExecutorService scheduledService = Executors.newSingleThreadScheduledExecutor();

public static void main(String[] args) {


    scheduledService.submit(() -> {

        System.out.println("p1");
        try 
        {
            TimeUnit.SECONDS.sleep(15);

        } catch (Exception e) {}

    });

    scheduledService.scheduleAtFixedRate(()-> System.out.println("p2"), 1, 5, TimeUnit.SECONDS);    
    }
}

Once p1 finishes, p2 will be immediately outputted three times, which shows that task was scheduled but couldn't be executed at requested time.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM