我需要在spring应用程序中创建一个全局threadpooltaskexecutor,它将负责在我的应用程序中运行多线程任务。
但是,对于每个请求,我都要限制从全局线程池使用的线程数。我应该如何确保每个请求都执行此限制?
例如。
我创建了一个全局线程池,最大池大小为50个线程。但是我想把每个请求的线程数限制为5个线程。但这5个线程只能从配置文件中定义的全局线程池中可用的50个线程中分配。
用于创建任务执行器的配置类。
@Configuration
public class ThreadPoolConfiguration {
@Value("${threadpool.corepoolsize}")
int corePoolSize;
@Value("${threadpool.maxpoolsize}")
int maxPoolSize;
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(corePoolSize);
pool.setMaxPoolSize(maxPoolSize);
pool.setWaitForTasksToCompleteOnShutdown(true);
return pool;
}
}
控制器类
@RestController
public class WebController {
@Autowired
ThreadPoolTaskExecutor threadPool;
@RequestMapping("/process")
public String process(){
String msg = "";
List<Future<String>> futureList = new ArrayList<>();
for(int threadNumber = 0; threadNumber < 5; threadNumber ++){
CallableWorker callableTask = new CallableWorker(String.valueOf(threadNumber));
Future<String> result = threadPool.submit(callableTask);
futureList.add(result);
}
for(Future<String> future: futureList){
try {
msg += future.get() + "#####";
} catch (Exception e){}
}
return msg;
}
}
免责声明:这只是我从一篇博客文章中得到的示例代码。
如何实现这样的设计?我没有看到任何可以创建的子线程池。我也不想为每个请求示例化线程池,因为那将是灾难性的。
有什么建议吗?
2条答案
按热度按时间cs7cruho1#
我的方法是创建一个类来限制任务。每个请求将创建一个节流阀,并将其所有任务提交给节流阀;节流阀会将前5个任务提交给执行器,并将其他任务放在一个列表中。提交的任务完成后,可以提交其他任务。
要确定任务何时完成,throttle可以定期轮询提交的任务,检查futures的isdone()方法以查看它们是否完成,或者它可以阻止一个future的get()方法,直到完成为止,并在此时检查另一个挂起的futures,或者如果您想变得复杂,请求线程可以在throttle上wait(),任务可以设置为在完成时通知throttle(),这样请求线程就可以唤醒并检查已完成的任务。
lx0bsm1f2#
解决这个问题的一种方法是创建可调用的方法来处理元素列表,而不是单个元素。
例如,如果要删除请求中的x项,可以创建x/5元素的列表,并将此列表传递给可调用函数。这样,通过代码,您可以确保每个请求最多只使用5个线程。不过,您必须小心处理异常情况(例如,您可以返回elementid到result enum的Map,其中结果可以是success、可重试的excepiton或不可重试的exception。)
这种方法可能会有所不同,具体取决于你想要实现什么。