当前位置: 首页 > 知识库问答 >
问题:

在自己的线程中运行每个Spring调度程序

冯流觞
2023-03-14

我有多个带有@dischedure注释的组件,我看到Spring一次只启动一个组件,即使它们被安排在同一时间运行。

@Scheduled(cron = "0 * * * * *") //run every minute
public void methodA() {
   log.info("Running method A");
   executeLongRunningJob("Finished method A");
}

@Scheduled(cron = "0 * * * * *") //run every minute
public void methodB() {
   log.info("Running method B");
   executeLongRunningJob("Finished method B");       
}

private void executeLongRunningJob(String msg) {
    Thread.sleep(70 seconds);
    System.out.println(msg);
}
Running method A
Finished method A
Running method B
Finished method B
Running method A
Finished method A
Running method B
Finished method B
... and so on
Running method A
Running method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
Running method A  
Running method B
Finished method A 
Finished method B 
Running method A 
Running method B 
Finished method A 
Finished method B
... and so on

共有1个答案

杭胜
2023-03-14

您是对的-默认情况下调度器使用大小为1的线程池,因此每个任务都是按顺序处理的。您可以通过将TaskSchedulerbean配置为所需的池大小来实现。考虑以下示例:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.Date;

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public TaskScheduler taskScheduler() {
        final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        return scheduler;
    }


    @Scheduled(fixedDelay = 2 * 1000L, initialDelay = 3 * 1000L)
    public void scheduled1() throws InterruptedException {
        System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled1");
        Thread.sleep(1000);
    }

    @Scheduled(fixedDelay = 3 * 1000L, initialDelay = 3 * 1000L)
    public void scheduled2() throws InterruptedException {
        System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled2");
        Thread.sleep(1000);
    }
}

它将在一个单独的线程中运行每个计划的任务,例如:

Tue Jul 18 20:21:50 CEST 2017 taskScheduler-1: scheduled2
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:53 CEST 2017 taskScheduler-1: scheduled1
Tue Jul 18 20:21:54 CEST 2017 taskScheduler-3: scheduled2
Tue Jul 18 20:21:56 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:58 CEST 2017 taskScheduler-4: scheduled2
Tue Jul 18 20:21:59 CEST 2017 taskScheduler-1: scheduled1
 类似资料:
  • 我正在尝试设置一个Java程序,其中每个线程都可以使用自己的代理。 现在我只找到了一种全局设置代理的方法。(http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html) 如前所述,这些设置会影响使用这些选项调用的VM的整个生命周期内的所有http连接。然而,使用该系统是可能的。setProperty()方法,使其具有

  • 问题内容: 我正在编写一个多线程Java程序,其中每个线程可能都需要将其标准输出重定向到一个单独的文件。每个线程都有其自己的文件。是否可以在“每个线程”的基础上重定向System.out或在所有线程上全局更改System.out? 问题答案: 是否可以基于“每线程”重定向System.out 不,这是不可能的。 是静态的,并且在JVM最初启动时,每个JVM都会作为系统类加载器的一部分进行加载。尽管

  • 我正在编写一个多线程Java程序,其中每个线程可能需要将其标准输出重定向到一个单独的文件。每个线程都有自己的文件。是否有可能在“每个线程”的基础上重定向System.out,还是所有线程对System.out全局更改?

  • 我尝试在每次创建活动时运行以下线程。它第一次工作,但如果我按下后退按钮并尝试再次导航到活动,它总是崩溃第二次。我怎样才能确保这个线程每次都运行成功呢?

  • 要求是定期运行一个Java应用程序(例如每天),向客户发送电子邮件/短信通知。环境是集群/高可用性,其中多个节点将同时处于活动状态。该应用程序将部署在所有节点上,但只有一个节点应该启动并运行,即使所有节点都配置为运行。如何实现这一点。在Java应用中,使用了石英调度器。 还需要一些关于如何在Linux机器上部署这个Java应用程序的指导(像Cron作业或其他一些方式)。要求是,这个应用程序应该在服