Поддержка SpringBoot для режима Future

Spring Boot

   У нас есть некоторые сложные операции и трудоемкие операции в реальных проектах, поэтому мы можем использовать многопоточность, чтобы полностью использовать ЦП и повысить пропускную способность системы. SpringBoot очень хорошо поддерживает многопоточность, что очень удобно для нашей разработки.
Шаблон   Future — очень распространенный шаблон проектирования в многопоточной разработке. Основная идея — асинхронный вызов. Когда мы выполняем метод, в методе есть несколько трудоемких задач, которые нужно делать одновременно, и когда мы не торопимся ждать результата, мы можем позволить клиенту вернуться сразу, а затем медленно рассчитать задачу в фоновом режиме.
  Когда нам нужно подождать, когда мы делаем что-то одно, тогда мы можем заняться другими делами в это время ожидания, чтобы мы могли полностью использовать время. Например, нам нужно время, чтобы заказать еду на вынос, поэтому мы можем почитать книгу или посмотреть фильм, пока ждем еду на вынос. Это типичный паттерн Future. Если это обычный режим, то это ждать еды на вынос, пока она есть, а затем читать книгу после того, как еда на вынос прибудет, что является огромной тратой времени.
  SpringBoot очень хорошо поддерживает режим Future, который можно реализовать с помощью простого кода.

1. Будущие методы

  • логическое значение отмены (логическое значение mayInterruptIfRunning); //Может отменить задачу во время выполнения задачи
  • логический isCancelled(); // Определяем, отменена ли задача Future
  • логическое значениеВыполнено(); // Определяем, завершена ли задача
  • V get();//Получить окончательный результат задачи, это блокирующий метод, который будет ждать выполнения задачи перед выполнением следующего кода
  • V get(длительный тайм-аут, блок TimeUnit); //Есть метод get, который часто ожидает.После того, как время ожидания истекло, вычисление все еще не завершено, и выдается исключение

2. Необходимые аннотации

  Springboot требует две аннотации для настройки многопоточности

  1. @EnableAsync
    Включите поддержку асинхронных задач, добавив @EnableAsync в класс конфигурации.
  2. @Async
    Добавление @Async к методу, который необходимо выполнить, указывает на то, что метод является асинхронным методом.Если он добавляется на уровне класса, это указывает на то, что все методы класса являются асинхронными методами.

3. Код конфигурации

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数
        taskExecutor.setCorePoolSize(8);
        //最大线程数
        taskExecutor.setMaxPoolSize(16);
        //队列大小
        taskExecutor.setQueueCapacity(100);
        taskExecutor.initialize();
        return taskExecutor;
    }
}

4.FutureService

@Service
public class FutureService {

    @Async
    public Future<String> futureTest() throws InterruptedException {
        System.out.println("任务执行开始,需要:1000ms");
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println("do:" + i);
        }
        System.out.println("完成任务");
        return new AsyncResult<>(Thread.currentThread().getName());
    }
}

[Примечание] Методы здесь автоматически внедряются с помощью ThreadPoolTaskExecutor, настроенного выше.

5. Протестируйте код

@Resource
private FutureService futureService;

@Test
public void futureTest() throws InterruptedException, ExecutionException {
    long start = System.currentTimeMillis();
    System.out.println("开始");
    //耗时任务
    Future<String> future = futureService.futureTest();
    //另外一个耗时任务
    Thread.sleep(500);
    System.out.println("另外一个耗时任务,需要500ms");

    String s = future.get();
    System.out.println("计算结果输出:" + s);
    System.out.println("共耗时:" + (System.currentTimeMillis() - start));
}

6. Результаты выполнения

开始
2019-01-07 23:50:34.726  INFO 14648 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService
任务执行开始,需要:1000ms
do:0
do:1
do:2
do:3
另外一个耗时任务,需要500ms
do:4
do:5
do:6
do:7
do:8
do:9
完成任务
计算结果输出:ThreadPoolTaskExecutor-1
共耗时:1016

Process finished with exit code 0

Задачи, выполнение которых раньше занимало не менее 1500 мс, теперь занимают всего 1016 мс. Поскольку трудоемкая задача 1 также выполняется одновременно с трудоемкой задачей 2, две задачи выполняются параллельно, что является преимуществом будущего режима.Выполнение других задач в течение времени ожидания может полностью использование времени.

[Примечание] Эта статья основана на SpringBoot 2.0.

GitHub-соединение