2016-07-21 3 views
4

Я хотел бы использовать пул потоков для обработки списка элементов, а затем дождаться их завершения. Я также должен иметь возможность таймаутировать его после 4-минутной обработки, если они еще не закончены.Вилка и присоединение без основной темы

Это то, что я в данный момент

ForkJoinPool threadPool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2); 

list.forEach(entry -> threadPool.execute(() -> { 
    // processing 
})); 

if (!threadPool.awaitQuiescence(4, TimeUnit.MINUTES)) { 
    // send alert about delay 
} 

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

+0

Почему бы просто не выполнить его в новой теме? И «иногда это будет выполняться в основном потоке» на самом деле не имеет смысла. Вы говорите, что результаты непоследовательны, так как в 'ForkJoinPool' выбирает, использовать ли основной поток или нет? –

+0

ForkJoinPool кажется непоследовательным. Я регистрируюсь в процессе обработки, который записывает используемый поток, и иногда он использует только те, которые называются ForkJoinPool-1-worker- [n], а другие - один из тех, которые его вызвали. – sparkdoo

+1

Невозможно избежать использования подающей нити. Подающая нить необходима для достижения приемлемого уровня производительности с предостережением, как я указываю здесь: http://coopsoft.com/ar/Calamity2Article.html#submit – edharned

ответ

0

Я думаю, проблема в том, что вы все еще итерации (list.forEach) в основной теме. Используйте параллельный поток и делегировать весь расчет в бассейне:

ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2); 

pool.execute(() -> { 
    list.parallelStream().forEach(item -> { 
     // processing 
    }); 
}); 

if (!pool.awaitQuiescence(4L, TimeUnit.MINUTES)) { 
    // send alert about delay 
} 

Я рекомендую прочитать this question (и данные ответы), чтобы увидеть, как использовать ForkJoinPool и параллельные потоки.

Смежные вопросы