Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java-Spring引导中运行同一进程的多个线程_Java_Multithreading_Spring Boot - Fatal编程技术网

如何在Java-Spring引导中运行同一进程的多个线程

如何在Java-Spring引导中运行同一进程的多个线程,java,multithreading,spring-boot,Java,Multithreading,Spring Boot,我有一个计划任务,它需要在执行时启动同一进程的多个线程。是否可以在进程启动时设置要启动的特定线程数 在应用程序类中,我配置了以下TaskExecutorbean @Bean("threadFooExecutor") public TaskExecutor getFooExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCor

我有一个计划任务,它需要在执行时启动同一进程的多个线程。是否可以在进程启动时设置要启动的特定线程数

在应用程序类中,我配置了以下
TaskExecutor
bean

    @Bean("threadFooExecutor")
    public TaskExecutor getFooExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("Foo-");
        return executor;
    }```

    @Bean("threadBarExecutor")
    public TaskExecutor getBarExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("Bar-");
        return executor;
    }
在进程类中配置的异步进程

    @Async("threadFooExecutor")
    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void print() {
        System.out.println(Thread.currentThread().getName() + " " + 1);
        System.out.println(Thread.currentThread().getName() + " " + 2);
        System.out.println(Thread.currentThread().getName() + " " + 3);
        System.out.println(Thread.currentThread().getName() + " " + 4);
    }

    @Async("threadBarExecutor")
    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void print2() {
        System.out.println(Thread.currentThread().getName() + " " + 1);
        System.out.println(Thread.currentThread().getName() + " " + 2);
        System.out.println(Thread.currentThread().getName() + " " + 3);
        System.out.println(Thread.currentThread().getName() + " " + 4);
    }

我希望看到这些线程中有2或3个同时运行,但我只看到每个线程每3秒运行一次更新:好的,根据您的评论,您需要以下内容:

public class ServiceOne {
    @Async
    public void bgTask() {
        System.out.println(Thread.currentThread().getName());
    }
}

public class ServiceTwo {
    @Autowired
    ServiceOne serviceOne;

    @Scheduled(fixedRate = 3000, initialDelay = 5000)
    public void scheduledRunner() {
        int i = 3;
        while (i-- >0 ) {
            serviceOne.bgTask();
        }
    }
}
这样,计划的方法将每三秒执行一次,它将产生三个并行的后台任务。InjectThingie用于AOP与默认的weaver一起工作,如果方法在同一个类中,默认的weaver将忽略其中一个注释

根据这一点,可能正在发生的是:

默认情况下,将搜索关联的调度程序定义:上下文中唯一的TaskScheduler bean,否则将搜索名为“TaskScheduler”的TaskScheduler bean;还将对ScheduledExecutorService bean执行相同的查找。如果两者都不可解析,将创建一个本地单线程默认调度程序,并在注册器中使用

我认为配置
ScheduledTaskRegistrar
可能会有所帮助:

public class SchedulerConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(4); // Number of simultaneously running @Scheduled functions
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);
    }

我认为您可以混合使用以下内容:
TaskExecutor/Executor
配置和调度程序执行任务的频率

此配置意味着每3秒执行一次任务:

@Scheduled(fixedRate = 3000, ...)
添加:
@Async(“threadBarExecutor”)
只意味着调度程序将使用特定的
执行器来运行任务

这并不意味着在已配置的
执行器
中,线程池大小未满时,它将被执行
所以,是的,这两个任务每3秒触发一次看起来很正常

如果您想以每3秒一次的特定次数并行运行这些任务,
@Scheduled
是不够的。
您应该使调度程序方法调用另一个
@Asynch
方法。这可以在同一个bean中定义,也可以在另一个bean中定义,这无关紧要

@Async("threadFooExecutor")
@Scheduled(fixedRate = 3000, initialDelay = 5000)
public void printRepeat3Times() {
    for (int i=0; i<3; i++){
         print();
    }
}


@Async("threadFooExecutor")
public void print() {
     // ...
}
@Async(“threadFooExecutor”)
@计划(固定速率=3000,初始延迟=5000)
public void printRepeat3次(){

对于(int i=0;如果这些任务应该安排,我正忙于一个项目,该项目要求我安排这些进程并启动多个线程。例如,为了参数起见,我希望每3秒看到每个进程的3个线程。您的任务可能太短,无法达到固定的速率。请尝试超过3秒的长任务。您应该会看到一些输出中有不同的线程名称。这是正确的。是的,但问题不是我没有看到线程重叠,我已经测试过了,问题是我需要线程每三秒执行3次。因此在执行2次后,我需要看到每个任务的6个输出。目前它只执行一次,然后等待下一步运行谢谢,我已经添加了这个,但是我得到了相同的结果。另外,我删除了我在应用程序类中的
任务调度器
实现,所有复制粘贴人员的输出没有任何变化:别忘了添加
@EnableScheduling