Ранее мы начали работать с Spring и TaskExecutor , таким образом, мы стали более знакомыми с тем, как использовать потоки в приложении Spring .
Однако использование исполнителя задач может быть обременительным, особенно когда нам нужно выполнить простое действие.
Асинхронные методы Spring приходят на помощь.
Вместо того, чтобы связываться с runnables и TaskExecutor, вы торгуете управлением исполнителя для простоты асинхронных функций.
Чтобы выполнить вашу функцию в другом потоке, все, что вам нужно сделать, это аннотировать ваши функции аннотацией @Async.
Асинхронные методы имеют два режима.
Режим огня и забывания: метод, который возвращает тип void.
|
1
2
3
4
5
6
7
|
@Async @Transactional public void printEmployees() { List<Employee> employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList(); employees.stream().forEach(e->System.out.println(e.getEmail())); } |
Режим поиска результатов: метод, который возвращает тип будущего.
|
1
2
3
4
5
6
|
@Async @Transactional public CompletableFuture<List<Employee>> fetchEmployess() { List<Employee> employees = entityManager.createQuery("SELECT e FROM Employee e").getResultList(); return CompletableFuture.completedFuture(employees); } |
Обратите особое внимание на то, что аннотации @Async не работают, если они вызываются «this». @Async ведет себя так же, как аннотация @Transactional. Поэтому вам нужно, чтобы ваши асинхронные функции были общедоступными. Вы можете найти больше информации в документации по aop прокси .
Однако использование только аннотации @Async недостаточно. Нам нужно включить возможность выполнения асинхронного метода Spring с помощью аннотации @EnableAsync в одном из наших классов конфигурации.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.gkatzioura.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.task.TaskExecutor;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;/** * Created by gkatzioura on 4/26/17. */@Configuration@EnableAsyncpublic class ThreadConfig { @Bean public TaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(4); executor.setMaxPoolSize(4); executor.setThreadNamePrefix("sgfgd"); executor.initialize(); return executor; }} |
Следующий вопрос — как мы объявляем ресурсы и пулы потоков, которые будут использовать асинхронные функции. Мы можем получить ответ из документации .
По умолчанию Spring будет искать определение связанного пула потоков: либо уникальный компонент TaskExecutor в контексте, либо компонент Executor с именем «taskExecutor» в противном случае. Если ни один из них не является разрешимым, SimpleAsyncTaskExecutor будет использоваться для обработки вызовов асинхронных методов.
Однако в некоторых случаях мы не хотим, чтобы один и тот же пул потоков выполнял все задачи приложения. Мы могли бы хотеть отдельные пулы потоков с различными конфигурациями, поддерживающими наши функции.
Для этого мы передаем аннотации @Async имя исполнителя, который мы можем использовать для каждой функции.
Например, настроен исполнитель с именем «specificTaskExecutor».
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Configuration@EnableAsyncpublic class ThreadConfig { @Bean(name = "specificTaskExecutor") public TaskExecutor specificTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.initialize(); return executor; }} |
Затем наша функция должна установить значение квалификатора, чтобы определить целевого исполнителя конкретного исполнителя или TaskExecutor.
|
1
2
3
4
|
@Async("specificTaskExecutor")public void runFromAnotherThreadPool() { System.out.println("You function code here");} |
В следующей статье мы поговорим о транзакциях по потокам.
Вы можете найти исходный код на github .
| Опубликовано на Java Code Geeks с разрешения Эммануила Гкациоураса, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Spring и Threads: Async
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |