ExecutorService: как предотвратить голодание потоков при создании барьеров синхронизации в потокахJAVA

Программисты JAVA общаются здесь
Anonymous
ExecutorService: как предотвратить голодание потоков при создании барьеров синхронизации в потоках

Сообщение Anonymous »

У меня возникла ситуация, для которой мне не удается найти четкое решение. Постараюсь объяснить максимально подробно.

У меня древовидная структура:

Код: Выделить всё

NODE A
NODE A.1
NODE A.2
NODE A.2.a
NODE A.2.b
NODE A.3
NODE A.3.a
NODE A.3.b
NODE A.3.c
NODE B
NODE B.1
NODE B.2
Мне нужно обработать корневой узел:

Код: Выделить всё

 public void process(final Node node) { ... }
Процесс узла включает в себя две вещи:

Код: Выделить всё

- some database queries
- the process of all children of these nodes
Другими словами, после обработки NODE.2.a и NODE.2.b NODE.2 может быть обработаны. Я обрабатываю узлы рекурсивно, ничего особенного.

Пока все хорошо. Теперь я хочу объявить глобальную службу-исполнитель с фиксированным количеством потоков. Я хочу обрабатывать дочерние узлы узла параллельно. Таким образом, NODE.2.a и NODE.2.b могут обрабатываться каждый в своем собственном потоке. Код будет выглядеть примерно так:

Код: Выделить всё

// global executor service, shared between all process(Node) calls
final ExecutorService service = Executors.newFixedThreadPool(4);

public void process(final Node node) {
// database queries
...

// wait for children to be processed
final CountDownLatch latch = new CountDownLatch(node.children().size());

for (final Node child : node.children()) {
service.execute(() -> {
process(child);
latch.countDown();
});
}
latch.await();
}
Проблема в том, что при достижении определенной глубины все потоки останавливаются в latch.await(). Мы достигли ситуации нехватки потоков.

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

Как это можно решить?

Подробнее здесь: https://stackoverflow.com/questions/458 ... n-barriers

Вернуться в «JAVA»