ForkJoinPool и будущее.Получить

предполагая, что у меня есть настройка ForkJoinPool со степенью параллелизма n, и что я называю параллельное вычисление следующим образом:

 workpool.submit(
            () -> {
                    objects.values().parallelStream().forEach(obj -> {
                        obj.foo();
                    });
                });

Я делаю это, чтобы гарантировать, что потоки, порожденные там, созданы внутри workpool (у меня есть разные компоненты системы, которые необходимо изолировать). Теперь предположим, что поток, в котором это вызывается, также выполняется внутри этого workpool, и я делаю:

 Future<?> wait =  workpool.submit(
            () -> {
                    objects.values().parallelStream().forEach(obj -> {
                        obj.foo();
                    });
                });
 wait.get()

1) я блокирую поток в ForkJoinPool? если я если бы все N потоков блокировались на фьючерсах, при попытке запланировать задачу в workpool это привело бы к тупику? Мне не ясно, означает ли" максимальная степень параллелизма " в ForkJoinPool, что (если есть n незаблокированных задач), всегда будет выполняться n потоков, или есть ли фиксированное количество потоков, независимо от того, заблокированы ли они. Что, если я использую wait.присоединяйтесь() вместоwait.join вместо этого (мне не нужны проверенные исключения как любое исключение этот код уже будет генерировать исключение runtimeexception. Если я правильно понимаю, join () позволит потокам выполнять задачи в очереди во время ожидания)

2) я все еще получаю преимущество легких задач forkjoin параллельного потока, если я создаю управляемый класс "обертки", выполнив () - > {}

3) Есть ли какой-либо недостаток/вверх, чтобы использовать это вместо этого (предполагая, что .join () действительно реализует поведение воровства работы, которое я думаю does):

        CompletableFuture.supplyAsync(this::mylambdafunction, workpool)  
             .thenAccept(this::mynextfunction);

1 ответов


ответ на вопрос 1: трудно узнать, будет ли ваш код блокировать, не видя фактических реализаций метода. Один из подходов к работе с блокирующим кодом-увеличить количество потоков в пуле forkjoin threadpool. Обычно число потоков в потоке forkjoin равно n+1 для вычислительных задач, где n=число процессоров. Или, если у вас есть блокировка ввода-вывода, Вы можете использовать ManagedBlocker.

ответ на вопрос 2: Да

ответ на вопрос 3: очевидным плюсом вашего кода completableFuture является то, что thenAccept не блокирует. Таким образом, элемент управления сразу же пройдет мимо вашего блока CompletableFuture к следующему оператору, не дожидаясь, тогда как в более раннем коде вы написали с пулом ForkJoin ожидание.get () будет блокировать, пока вы не получите ответ, и не будет продолжаться до тех пор.