简体   繁体   English

Java ScheduledExecutorService中使用的调度算法

[英]Scheduling algorithm used in Java ScheduledExecutorService

I am using ScheduledExecutorService for scheduling multiple java jobs. 我使用ScheduledExecutorService来安排多个java作业。 I wanted to know what happen in the following scenario: 我想知道在以下场景中发生了什么:

If I am using, 如果我正在使用,

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

for scheduling 5 jobs with a thread pool size of one 用于调度线程池大小为1的5个作业

p1 - 5(execution interval in minutes) p1 - 5(执行间隔,以分钟为单位)

p2 - 5 p2 - 5

p3 - 5 p3 - 5

p4 - 7 p4 - 7

p5 - 10 第5-10页

After 5 minutes p1, p2, and p3 would be active for contention. 5分钟后,p1,p2和p3将激活争用。

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. 现在在第7分钟,说p1和p2完成并且p4变为活动状态,但是p3是内存密集型的并且最终使用整个内存,然后我认为由于内存不足,调度程序本身不会被调度。 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. ScheduledExecutorService是一个接口,它不会定义您要询问的任何内容。

So the answer depends on the concrete implementation you are using. 所以答案取决于您使用的具体实现。 If you use Executors.newScheduledThreadPool then you are effectively using a ScheduledThreadPoolExecutor . 如果您使用Executors.newScheduledThreadPool那么您实际上正在使用ScheduledThreadPoolExecutor The javadoc says: javadoc说:

Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission. 按照先进先出(FIFO)提交顺序启用计划完全相同执行时间的任务。

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. 如果你不这样做,你会得到一个OutOfMemoryError。

There will be no contention between tasks after 5 minutes. 5分钟后任务之间不会发生争用。

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. 任务被传递到队列中,如果没有可用的线程来执行它们,它们将按FIFO顺序执行,至少给定ScheduledThreadPoolExecutor实现。

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) ScheduledFuture scheduleAtFixedRate(Runnable命令,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. 即执行将在initialDelay之后开始,然后是initialDelay + period,然后是initialDelay + 2 * period,依此类推。

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. 内存已经为调度程序实例“保留”,如果任务耗尽所有剩余的内存,JVM将不会从调度程序中获取它们。 This can and will result with OutOfMemoryError . 这可能会导致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. 如果池中只有一个线程,则将调度任务p2p3,但在有可用线程之前不会执行它们。

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. 一旦p1完成, p2将立即输出三次,这表明任务已安排但无法在请求的时间执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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