我正在使用ThreadPoolExecutor服务处理我的代码中的项目列表。我将从数据库中获取那些项目列表。这里的问题是Tomcat线程nio-8080-exec-5连续查询数据库,即使executor服务线程仍在处理较早的提取项。仅当执行器服务没有要处理的项目以及工作队列为空时,才需要查询数据库。请在下面找到我的示例代码:
private void start(){
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 240L, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
boolean itemsPresent =true;
while(itemsPresent){
log.info("Fetch Items from DB");
List<Item> itemList = fetchItemsDB();
log.info("Total Items fetched from DB: {}", itemList.size());
if(!itemList.isEmpty()){
itemList.forEach(itemInfo -> executorPool.execute(() -> processItems(itemInfo)));
}
else{
itemsPresent =false;
}
}
}
非常感谢您的帮助:)
请在下面找到日志详细信息:
2018-12-25 19:03:54.189 INFO 4828 --- [ main] com.sample.MyApplication : Running with Spring Boot v1.5.2.RELEASE, Spring v4.3.7.RELEASE
2018-12-25 19:03:54.189 INFO 4828 --- [ main] com.sample.MyApplication : No active profile set, falling back to default profiles: default
2018-12-25 19:03:58.846 INFO 4828 --- [ main] com.sample.MyApplication : Started MyApplication in 5.209 seconds (JVM running for 5.66)
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] o.a.c.c.C.[Tomcat].[localhost].[/]: Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Inside Start method !!!!
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Fetch Items from DB
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Total Items fetched from DB: 20
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-5] com.sample.MyApplication: started to process: 1
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-] com.sample.MyApplication: started to process: 2
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-5] com.sample.MyApplication: started to process: 4
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-1] com.sample.MyApplication: started to process: 6
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-9] com.sample.MyApplication: started to process: 11
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-7] com.sample.MyApplication: started to process: 12
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-8] com.sample.MyApplication: started to process: 5
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-3] com.sample.MyApplication: started to process: 9
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Fetch Items from DB
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Total Items fetched from DB: 20
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Fetch Items from DB
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Total Items fetched from DB: 20
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Fetch Items from DB
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Total Items fetched from DB: 20
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Fetch Items from DB
2018-12-25 19:03:58.846 INFO 4828 --- [nio-8080-exec-5] com.sample.MyApplication: Total Items fetched from DB: 15
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-1] com.sample.MyApplication: started to process: 3
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-1] com.sample.MyApplication: started to process: 7
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-9] com.sample.MyApplication: started to process: 8
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-7] com.sample.MyApplication: started to process: 10
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-8] com.sample.MyApplication: started to process: 13
2018-12-25 19:03:58.846 INFO 4828 --- [pool-1-thread-3] com.sample.MyApplication: started to process: 14
答案 0 :(得分:1)
如果项目处理任务和从数据库中获取任务是互斥的,为什么不将它们按顺序写在单个线程中?
答案 1 :(得分:1)
据我了解,您需要在执行程序服务中所有可运行对象完成后触发一个事件(调用方法)。
没有干净的方法可以实现这一目标。您可以使用ExecutorService.submit(Runnable)
。此方法将返回Future<?>
,它是可运行结果的句柄。
话虽如此,您可以为每个将来完成的操作增加一个AtomicInteger
计数器。当此计数器值等于列表大小时,您可以轮询数据库以获取更多记录。