首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring @调度配置

问Spring @调度配置
EN

Stack Overflow用户
提问于 2017-12-19 16:39:18
回答 2查看 728关注 0票数 0

使用@Scheduling按@调度(fixedRate= 10000)运行方法,并通过实现SchedulingConfigurer设置@调度线程

代码语言:javascript
复制
    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }

如果我使用Thread.sleep或Lock,除非Thread.sleep唤醒或锁被清除,否则执行器不会创建其他线程。

有人能解释内部工作,如果我有10个池大小,他们10个线程应该以10000毫秒的速度创建。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-20 12:59:21

基本上,这样的行为来自于ScheduledExecutorService实现,spring在内部使用。如果要运行此代码,您将注意到相同的行为:

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
    executor.schedule(() -> {
        System.out.println("Running task in thread " + Thread.currentThread().getId());
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            System.out.println("interrupted while sleeping");
        }
    }, 1000, TimeUnit.MILLISECONDS);
    Thread.sleep(10000);
    executor.shutdownNow();
}

当您将任务提交到计划线程池时,它将使用RunnableScheduledFuture包装,然后传递给delayedExecute方法。此方法将任务添加到任务队列中,如果当前工作人员的数量少于corePoolSize,则启动新的工作人员。工作者试图从队列中获取一个任务,并处理它调用run方法。有一个专用的DelayedWorkQueue实现,它只在任务准备好执行时才返回任务。下面是run方法RunnableScheduledFuture的样子:

代码语言:javascript
复制
    /**
     * Overrides FutureTask version so as to reset/requeue if periodic.
     */
    public void run() {
        boolean periodic = isPeriodic();
        if (!canRunInCurrentRunState(periodic))
            cancel(false);
        else if (!periodic)
            ScheduledFutureTask.super.run();
        else if (ScheduledFutureTask.super.runAndReset()) {
            setNextRunTime();
            reExecutePeriodic(outerTask);
        }
    }

如您所见,它调用runAndReset中的实际任务逻辑,计算下一个运行时间,并再次向队列提交相同的更新任务(reExecutePeriodic几乎与schedule相同)。对于所有的执行,只有一个定期任务,在上次执行完成后,会一次又一次地重新提交,并进行更新。因此,这样的线程池在任何给定时刻只运行每种任务类型的单个实例,并且只针对不同类型的任务进行缩放。

如果您对spring调度任务的方式感兴趣,请查看ScheduledTaskRegistrar类,特别是scheduleFixedDelayTask方法。

票数 0
EN

Stack Overflow用户

发布于 2017-12-19 16:52:04

在使用线程池的情况下:默认情况下,池中将有10个线程(已经初始化)。第一次执行@调度时,该函数将在池中的线程中执行(现在剩下9个线程),如果函数尚未完成并再次执行@调度,则您的函数将在池中的其他线程中执行,因此您的池中保留了8个线程。(8个空闲线程,2个正在运行的线程)

如果不使用线程池,则只使用一个线程。

春季文件:

如果不提供“池大小”属性,默认线程池将只有一个线程。调度程序没有其他配置选项。

https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/scheduling.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47891397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档