Как использовать ForkJoinPool в Spring Boot @Async? - PullRequest
0 голосов
/ 25 января 2019

Я хочу использовать ForkJoinPool в моем весеннем загрузочном проекте с аннотацией @Async, например ThreadPoolTaskExecutor

Например: -

 @Bean("threadPoolTaskExecutor")
    public TaskExecutor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setMaxPoolSize(1000);
        executor.setThreadNamePrefix("Async-");
        return executor;
    }

я использую https://dzone.com/articles/spring-boot-creating-asynchronous-methods-using-as эта ссылка в моем коде, но я хочу использовать ForkJoinPool вот так.

Ответы [ 4 ]

0 голосов
/ 25 января 2019

Я не знаю, почему вы хотите это сделать, но все же вы можете использовать ForkJoinPool для @Async, поскольку ForkJoinPool реализует класс Executor

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

1012 * конфиг *

@Bean("threadPoolTaskExecutor")
public Executor getAsyncExecutor() {
    ForkJoinPool pool = new ForkJoinPool();
    return pool;
}

Услуги

@Async("threadPoolTaskExecutor")
public void testRun()  {
    System.out.println(Thread.currentThread().getName());
}

выход

ForkJoinPool-1-worker-1

А если вам очень интересно использовать ForkJoinPool, используйте CompletableFuture.async методы вместо пружинной загрузки @Async docs

Все асинхронные методы без явного аргумента Executor выполняются с использованием ForkJoinPool.commonPool () (если только он не поддерживает уровень параллелизма, равный по крайней мере двум, и в этом случае для выполнения каждой задачи создается новый поток)

0 голосов
/ 25 января 2019

Чтобы включить возможность выполнения асинхронного метода Spring, вы можете использовать аннотацию @EnableAsync в классе конфигурации.

@Configuration
@EnableAsync
public class ThreadConfig {
    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("prate");
        executor.initialize();
        return executor;
    }
}

В некоторых случаях вам не нужно, чтобы один и тот же пул потоков выполнял все задачи приложения. вам могут потребоваться отдельные пулы потоков с разными конфигурациями, поддерживающие наши функции. Таким образом, вы можете настроить конкретные ThreadPoolExecutor, как -

@Configuration
@EnableAsync
public class ThreadConfig {
    @Bean(name = "specificTaskExecutor")
    public TaskExecutor specificTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.initialize();
        return executor;
    }
}

Теперь функция должна установить значение квалификатора для определения целевого исполнителя конкретного исполнителя или TaskExecutor.

@Async("specificTaskExecutor")
public void runFromAnotherThreadPool() {
    System.out.println("test here");
}
0 голосов
/ 25 января 2019

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

Итак, при базовом использовании вы можете сделать:

CompletableFuture.runAsync(() -> doSomething(), ForkJoinPool.commonPool());

Вы также можете создать пользовательский ForkJoinPool в асинхронном режиме. Рабочие в ForkJoinPool в асинхронном режиме обрабатывают задачи в порядке FIFO (первым пришел, первым вышел). По умолчанию ForkJoinPools обрабатывает такие задачи в порядке LIFO (последний пришел, первый вышел). Также настройка асинхронного режима касается только разветвленных задач, которые никогда не объединяются. Может использоваться для задач в стиле событий, которые отправляются, но никогда не присоединяются (задачи, которые выполняются по своим побочным эффектам, а не для возврата результата, который будет обработан задачей разветвления, а затем присоединения).

Вы можете создать собственный ForkJoinPool с заданным параллелизмом в асинхронном режиме, например так (первый параметр - это размер пула, последний - bool asyncMode):

ForkJoinPool pool = new ForkJoinPool(
             6, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);

Итак, что вы ищете:

    @Bean("threadPoolTaskExecutor")
    public Executor getAsyncExecutor() {
    ForkJoinPool pool = new ForkJoinPool(
             6, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
        return pool;
    }
0 голосов
/ 25 января 2019

На мой взгляд, вы не можете объединить аннотацию @Async с классом ForkJoinPool. ForkJoinPool предназначен для разделения одной задачи на подзадачу для ее параллельного выполнения и объединения в результат. Параллельный поток - с использованием ForkJoinPool за кадром. Для выполнения задачи с использованием ForkJoinPool необходимо реализовать интерфейс RecursiveTask или RecursiveAction. Я никак не мог понять, как мы можем использовать эти вещи вместе.

...