如何在Java SpringBoot中通过接收参数来命名线程?

yvgpqqbh  于 2022-10-30  发布在  Spring
关注(0)|答案(3)|浏览(141)

我是SpringBoot的新手。现在我希望基于参数命名一个线程。
举一个简单的例子,我目前正在使用@Async表示法创建一个异步方法

@PostMapping
public void requestMethod(@RequestBody String id){
    ...
    asyncMethod(id);    
}
@Async
public void asyncMethod(String id){
    ...
}

一旦有一个POST请求发送到requestMethod,该方法将在一个新线程中创建一个异步方法。该线程的名称与作为id接收的参数相同。
因为程序中会有很多异步方法。异步方法会在无限循环中运行。所以,我想根据线程的名称来终止线程。但是我该怎么做呢?
如果有任何不明确的地方,请告诉我。提前谢谢。

xn1cxnb4

xn1cxnb41#

您不能这样做。您最好指定TaskExecutor并在此处设置线程前缀名称。

@Bean
@Qualifier(SOME_PUBLIC_STATIC_FINAL_VARIABLE)
public Executor myExecutor() {
    int corePoolSize = 4, maxPoolSize = 8;
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    log.info("Will use {}/{} thread pool for {}", executor.getCorePoolSize(), executor.getMaxPoolSize(), taskName);
    executor.setThreadNamePrefix(ADD_YOUR_PREFIX_HERE);
    executor.initialize();
    return executor;
}

然后在Async注解上,指定Executor,例如@Async(SOME_PUBLIC_STATIC_VARIABLE)

4xrmg8kj

4xrmg8kj2#

最简单的方法就是自己设置线程名

@Async
public void asyncMethod(String id){
    Thread.currentThread().setName("thread-" + id);
    ...
}
des4xlb0

des4xlb03#

Aid Hadzic的答案是正确的,但它还缺少另一件事。在您的自定义ThreadExecutor中,您可以设置一个ThreadFactory。

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadFactory(new ThreadFactory() {

    AtomicInteger threadCounter = new AtomicInteger(0);

    @Override
    public Thread newThread(Runnable r) {
        Thread namedThread = new Thread(r);
        namedThread.setDaemon(true);                        
        namedThread.setName("my-custom-thread-" + threadCounter.incrementAndGet());
        return namedThread;
    }
});

这将产生具有指定名称的线程,并且当您创建更多线程时,它们的编号甚至会增加。
设置守护程序线程将允许应用程序关闭,即使线程仍处于活动状态(与不允许应用程序关闭的用户线程相反)。
现在,为了停止一个特定的线程,我认为你需要在执行程序之外存储对创建的线程的引用,并强制停止它们,或者使用CompleteableFuture而不是@Async注解,但这超出了这个答案的范围。

相关问题