Проблема с ExecutorService

Я использую службу ThreadPoolExecutor для обработки списка элементов в моем коде. Я получу этот список элементов из базы данных. Проблема здесь в том, что поток Tomcat nio-8080-exec-5 постоянно запрашивает БД, хотя потоки службы исполнителя все еще обрабатывают ранее извлеченные элементы. Мне нужно, чтобы БД запрашивалась только тогда, когда у службы исполнителя нет элементов для обработки и когда рабочая очередь пуста. Пожалуйста, найдите мой пример кода ниже:

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

person Community    schedule 28.12.2018    source источник


Ответы (2)


Если задачи обработки элементов и задачи извлечения из базы данных являются взаимоисключающими, почему бы не написать их последовательно в одном потоке?

person aaruja    schedule 29.12.2018

Насколько я понимаю, вам нужно инициировать событие (вызвать метод), когда все runnables будут завершены в службе-исполнителе.

Нет чистого способа добиться этого. Вы можете использовать ExecutorService.submit(Runnable). Этот метод вернет Future<?>, который является дескриптором результата выполнения.

При этом вы можете увеличивать счетчик AtomicInteger для каждого завершенного будущего. Когда это значение счетчика равно размеру списка, вы можете опросить свою базу данных для получения дополнительных записей.

person YetAnotherBot    schedule 29.12.2018