JavaSpring中的受控threadpoolexecutor

ggazkfy8  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(312)

我需要在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;
    }
}

免责声明:这只是我从一篇博客文章中得到的示例代码。
如何实现这样的设计?我没有看到任何可以创建的子线程池。我也不想为每个请求示例化线程池,因为那将是灾难性的。
有什么建议吗?

cs7cruho

cs7cruho1#

我的方法是创建一个类来限制任务。每个请求将创建一个节流阀,并将其所有任务提交给节流阀;节流阀会将前5个任务提交给执行器,并将其他任务放在一个列表中。提交的任务完成后,可以提交其他任务。
要确定任务何时完成,throttle可以定期轮询提交的任务,检查futures的isdone()方法以查看它们是否完成,或者它可以阻止一个future的get()方法,直到完成为止,并在此时检查另一个挂起的futures,或者如果您想变得复杂,请求线程可以在throttle上wait(),任务可以设置为在完成时通知throttle(),这样请求线程就可以唤醒并检查已完成的任务。

lx0bsm1f

lx0bsm1f2#

解决这个问题的一种方法是创建可调用的方法来处理元素列表,而不是单个元素。
例如,如果要删除请求中的x项,可以创建x/5元素的列表,并将此列表传递给可调用函数。这样,通过代码,您可以确保每个请求最多只使用5个线程。不过,您必须小心处理异常情况(例如,您可以返回elementid到result enum的Map,其中结果可以是success、可重试的excepiton或不可重试的exception。)
这种方法可能会有所不同,具体取决于你想要实现什么。

相关问题