Как бороться с зависанием потока в Java ThreadPoolExecutor? - PullRequest
0 голосов
/ 05 апреля 2019

Я использую Executors.newFixedThreadPool(THREADS), где THREADS=20 для асинхронной отправки событий через службу отдыха. Пару недель назад у меня возникли неожиданные проблемы, когда служба отдыха, которую я потребляю, перестала работать или стала реагировать медленнее.

1. Во-первых, LinkedBlockingQueue, управляемый пулом потоков, столкнулся с узким местом, поскольку не мог завершать процессы быстрее, чем создавались новые процессы. Таким образом, в конечном итоге он достиг максимально допустимой емкости (Integer.MAX_VALUE), и значительная часть памяти кучи использовалась в очереди.

2. Во-вторых, хотя служба отдыха восстановилась и снова начала своевременно реагировать, пул потоков, казалось, находился в состоянии «зависания», когда больше событий не отправлялось. Мне пришлось перезапустить приложение, чтобы исправить проблему и отправить события обратно.

Вот вывод утилиты Memory Analyzer Tool с дампом кучи:

Один экземпляр "java.util.concurrent.ThreadPoolExecutor" загружен "" занимает 2 518 687 016 (94,69%) байтов. на экземпляр ссылается com.despegar.flights.keeper.concurrent.trace.TraceAwareExecutorServiceImpl @ 0x695cf3550, загружается "sun.misc.Launcher $ AppClassLoader @" 0x694cfd810 ".

Ключевые слова java.util.concurrent.ThreadPoolExecutor sun.misc.Launcher $ AppClassLoader @ 0x694cfd810

И статическое состояние ThreadPoolExecutor:

Type   |Name          |Value
----------------------------------
int    |TERMINATED    |1610612736
int    |TIDYING       |1073741824
int    |STOP          |536870912
int    |SHUTDOWN      |0
int    |RUNNING       |-536870912
int    |CAPACITY      |536870911
int    |COUNT_BITS    |29
----------------------------------

Вот код:

public AsyncDispatchManager() {
    this.executorService = new TraceAwareExecutorServiceImpl(Executors.newFixedThreadPool(THREADS));
}

public void execute(String name, Runnable runnable) {
    this.executorService.submit(this.adaptRunnable(name, runnable));
}

Что касается очереди, я не хочу тратить в ней больше ресурсов, поэтому я бы применил ограниченную очередь и политику отклонения для этих ситуаций, поскольку я не хочу потерять некоторые события.

Как вы думаете, есть более подходящее решение?

С висящими нитями я застрял. Я не понимаю фоновую проблему и как ее решить.

Кто-то сталкивался с такими проблемами?

Буду очень признателен за любое предложенное решение или информацию.

...