spring - 是否可以使用 Spring Boot 运行较长的任务?

标签 spring multithreading spring-boot threadpoolexecutor

我想使用 TaskExecutor 通过 Spring Boot 运行几个长任务。我想让多个 rfid 读取器运行并连续获取元素标签。然后我需要使用这些标签来更新数据库。到目前为止,我还无法使用 Spring Boot 多次运行任务。这可能吗?

我正在创建一个 @Component 阅读器类。创建时,我启动监听器服务和监听器来跟踪标签。我有 startMessageService 和 setReaderConfig 方法。第一种方法是启动消息监听器服务,以便在读取器进入时接收带有标签信息的消息。第二种方法将读取器设置为自主读取,因此当标签经过读取器时,读取器会向听众和我收到消息。

run 方法基本上让读者在消息进来时继续阅读。但由于某种原因,代码没有按照我想要的方式工作。一旦读者收到标签,我应该会收到一条消息,但我没有。

底部是我的 threadpooltaskexecutor bean。

我不确定我错过了什么。

@Component
@Scope("prototype")
public class AlienReader extends AlienClass1Reader implements 
TagTableListener, MessageListener, Runnable{
 private String ipaddress;
 private int port;
 private String username;
 private String password;
 int serviceport;

public AlienReader(String ipaddress, int port, String username, String pwd, 
int serviceport) throws UnknownHostException, AlienReaderException, 
InterruptedException{
    super(ipaddress, port);
    this.ipaddress=ipaddress;
    this.port=port;
    this.username=username;
    this.password=pwd;
    this.serviceport=serviceport;
    startMessageService();
    setReaderConfig();

}

}

@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(15);
    executor.setMaxPoolSize(42);
    executor.setQueueCapacity(11);
    executor.setThreadNamePrefix("threadPoolExecutor-");
    executor.setWaitForTasksToCompleteOnShutdown(true);
    executor.initialize();
    return executor;
}

最佳答案

Spring Boot 没有施加任何限制;如果您可以使用 Java 或其他语言来完成此操作,那么您应该也可以使用 Java + Spring Boot 来完成此操作。

什么是 Spring Boot

需要明确的是,Spring Boot 基本上只是一个用于构建 Spring 项目的框架,这些项目在历史上相当复杂,并且有大量的样板代码。你可以制作spring boot命令行应用程序或Web应用程序(这是比较正常的)。我相信还会有更多选择。

因此,Spring Boot 可以轻松地从 applicaiton.properties 文件中公开配置、自动连接所有 spring bean、设置 Controller 的连接等,从而为您提供领先优势。但它并不限制代码你写;它只是减少了它。

您的问题

您可以使用执行程序服务来运行任意数量的长时间运行的任务,只要您的 PC/服务器可以处理它们。

这是一个工作的 Spring Boot 示例,它并行或一分钟运行两个不同的任务。它们可以永远持续下去并做任何事情,并且您可以轻松地将其扩展到数百个任务。

import org.apache.catalina.core.ApplicationContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

@SpringBootApplication
public class App {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(App.class, args);
        App app = run.getBean(App.class);
        app.run();
    }

    private void run() {
        Runnable r1 = () -> {
            for(int i = 0; i < 30; ++i) {
                System.out.println("task 1");
                try {Thread.sleep(1000);} catch(Exception ignored) {}
            }
        };

        Runnable r2 = () -> {
            for(int i = 0; i < 30; ++i) {
                System.out.println("task 2");
                try {Thread.sleep(1000);} catch(Exception ignored) {}
            }
        };

        //Create an executor service with 2 threads (it can be like 50
        //if you need it to be).  Submit our two tasks to it and they'll
        //both run to completion (or forever if they don't end).
        ExecutorService service = Executors.newFixedThreadPool(2);
        service.submit(r1);
        service.submit(r2);

        //Wait or completion of tasks (or forever).
        service.shutdown();
        try { service.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS); }
        catch (InterruptedException e) { e.printStackTrace(); }
    }
}

更多信息

  • 如果您最终需要获取结果并等待结果,则可以安排可调用项而不是可运行项。
  • 如果您除了需要长时间运行的任务外还需要计划任务,那么执行程序服务有很多变体。
  • 您可以使用所需的任意数量的线程;只需增加 10 即可:)。
  • 这个特定的应用程序可能作为命令行应用程序更好 - 但我将其设置为正常的 Spring Boot Web 类型,以防您需要 Controller /等来提供任务检查端点或其他内容。它非常无关紧要,因为您主要是在询问任务本身。不过,此应用程序一旦完成就不会终止,除非您添加 System.exit() 因为它期望成为一个长期存在的网络应用程序。

关于spring - 是否可以使用 Spring Boot 运行较长的任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52105088/

相关文章:

java - ajax与Spring

java - 如何通知 PipedInputStream 线程 PipedOutputStream 线程已写入最后一个字节?

java - Spring Boot Test 未检测测试类中的静态嵌套 @Named 组件

java - 两个线程如何进入两个持有同一对象锁的同步块(synchronized block)

java - 如何使 Runnable 的内部类实现与 java 中的 Executor 一起工作?

java - 长时间发送请求时出现 org.springframework.transaction.CannotCreateTransactionException

java - Spring 启动 : get command line argument within @Bean annotated method

java - 如何使用spring aop记录方法链

Spring Boot - Spring组件中的@Configuration类为null

java - 如何在 Spring Security 中禁用 'X-Frame-Options' 响应 header ?