Java 使用ExecutorService/ThreadPool时解耦任务提交和结果处理
我有一个用例,在这个用例中,我应该设置一个按特定时间间隔触发的计划作业。任务是根据特定条件获取工作项(如果存在)并对其进行处理。在处理这些项目时,我尝试使用一个fixedThreadPool和Executor并并行处理它们 我希望主线程是一个获取工作项的计划作业,它只需将任务提交给执行者,然后继续下一次迭代。但是我的任务也会返回处理结果,因此我需要读取每个任务的结果并相应地处理它们。因为我必须阅读结果,所以我无法在将任务提交给执行者时结束主线程处理。主线程(技术上)正在等待任务完成并处理结果,然后结束其执行 我的轮询类-Poller.java-它以一定的频率进行轮询Java 使用ExecutorService/ThreadPool时解耦任务提交和结果处理,java,scheduled-tasks,threadpool,executorservice,java.util.concurrent,Java,Scheduled Tasks,Threadpool,Executorservice,Java.util.concurrent,我有一个用例,在这个用例中,我应该设置一个按特定时间间隔触发的计划作业。任务是根据特定条件获取工作项(如果存在)并对其进行处理。在处理这些项目时,我尝试使用一个fixedThreadPool和Executor并并行处理它们 我希望主线程是一个获取工作项的计划作业,它只需将任务提交给执行者,然后继续下一次迭代。但是我的任务也会返回处理结果,因此我需要读取每个任务的结果并相应地处理它们。因为我必须阅读结果,所以我无法在将任务提交给执行者时结束主线程处理。主线程(技术上)正在等待任务完成并处理结果,然
public void startPollingProcess() {
try {
List<RenderingsLogEntity> extractionLogDelta = fetchWorkItems();
if (extractionLogDelta != null && !extractionLogDelta.isEmpty()) {
processor.processWorkItems(extractionLogDelta);
}
}
}
public void startPollingProcess(){
试一试{
List extractionLogDelta=fetchWorkItems();
if(extractionLogDelta!=null&&!extractionLogDelta.isEmpty()){
processor.processWorkItems(extractionLogDelta);
}
}
}
我的处理器类-Processor.java
// initializing the executor at some point in the class. And the thread pool will be using a worker queue with bounded capacity. If the queue is full for any reason and cant take any more tasks it will throw a RejectedExecutionException as you can see
ExecutorService executorService = new ThreadPoolExecutor(5, 5,
0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(3000))
public void processWorkItems(List<RenderingsLogEntity> workItems) {
List<Future<ProcessingResult>> processingResultsList = new ArrayList<>();
try {
// each task is submitted to the thread pool of bounded queue size. I would want the main thread to just submit these tasks. If any exception handle that.
for (WorkItem item : workItems) {
processingResultsList.add(executorService.submit(() -> furtherProcessing(item)));
}
} catch (RejectedExecutionException e) {
// do something in case of exception
}
}
// Passing the handle on Future Results to a different method
if (!deltaProcessingResultList.isEmpty())
publishResults(deltaProcessingResultList);
}
private void publishResults(List<Future<ProcessingResult>> processingResultsList) {
try {
// Reading the results of each task and handling it. This is still being done by the main thread and result.get() is a blocking call. My polling execution is not complete until I handle these results. But I want that to be done by someone else and I want my polling to continue
for (Future<ProcessingResult> result : deltaProcessingResultList) {
ProcessingResult resultStatus = result.get();
// handle the result accordingly
}
} catch (InterruptedException | ExecutionException e) {
logger.error(e.getMessage(), e);
}
}
//在类中的某个点初始化执行器。线程池将使用容量有限的工作队列。如果队列因任何原因已满,并且无法执行更多任务,它将抛出RejectedExecutionException,如您所见
ExecutorService ExecutorService=新线程池Executor(5,5,
0L,TimeUnit.ms,新阵列锁定队列(3000))
公共无效进程工作项(列表工作项){
List processingResultsList=new ArrayList();
试一试{
//每个任务都提交到队列大小有界的线程池。我希望主线程只提交这些任务。如果有异常,请处理这些任务。
用于(工作项项目:工作项){
processingResultsList.add(executorService.submit(()->进一步处理(项目));
}
}捕获(拒绝执行异常e){
//万一发生异常,做点什么
}
}
//将未来结果的句柄传递给其他方法
如果(!deltaProcessingResultList.isEmpty())
发布结果(deltaProcessingResultList);
}
私有void publishResults(列表处理结果列表){
试一试{
//读取每个任务的结果并进行处理。这仍由主线程和result.get()执行。get()是一个阻塞调用。在处理这些结果之前,我的轮询执行不会完成。但我希望其他人完成此操作,并且我希望我的轮询继续
用于(未来结果:deltaProcessingResultList){
ProcessingResult resultStatus=result.get();
//相应地处理结果
}
}捕获(中断异常|执行异常e){
logger.error(e.getMessage(),e);
}
}
听起来像是要在工作线程中处理WorkItem和发布结果
public void processWorkItems(List<RenderingsLogEntity> workItems) {
try {
for (WorkItem item : workItems) {
executorService.submit(() -> {
ProcessingResult result = furtherProcessing(item);
publishResult(result);
});
}
} catch (RejectedExecutionException e) {
// handle exception
}
}
public void进程工作项(列表工作项){
试一试{
用于(工作项项目:工作项){
executorService.submit(()->{
ProcessInResult结果=进一步处理(项目);
发布结果(result);
});
}
}捕获(拒绝执行异常e){
//处理异常
}
}