Spring @Async против завершаемой асинхронной работы в будущем - PullRequest
0 голосов
/ 20 декабря 2018

Возможно, я делал что-то не так.Итак, у меня есть Spring @Async

Допустим, у меня есть этот кусок кода

@Async("poolbeanname") 
Function () {
     // some code 
}

У меня есть еще один, скажем, у меня есть этот кусок кода

@Async("poolbeanname") 
Function () {
     CompletableFuture.runAsync{ new Runnable ()...} 
} 

Теперь со вторым кодом, который я вижу, некоторые потоки были порождены, но первый подход, кажется, не порождает больше одного?

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018
@Async("poolbeanname") 
Function () {
}

Приведенный выше фрагмент будет выполняться асинхронно с использованием пула потоков, если у вас есть @EnableAsync в классе конфигурации.

@Configuration
@EnableAsync

или

@SpringBootApplication
@EnableAsync

Когда асинхронный режимКогда Spring активирован, Spring будет искать пользовательский TaskExecutor или bean-компонент executor. Если он не найден, по умолчанию будет использоваться собственный taskExecutor.

Проверьте в журнале строку, в которой написано Initializing ExecutorService.... Из коробки этоговорит, что он инициализировал o.s.s.concurrent.ThreadPoolTaskExecutor, который по умолчанию даст вам размер пула ядра 1.

Чтобы переопределить исполнителя, нужно только добавить фабричный метод в класс конфигурации для Executor.

@Bean
public Executor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setCorePoolSize(10);
    threadPoolTaskExecutor.setMaxPoolSize(50);
    //etc...
    return threadPoolTaskExecutor;
}

Если исполнитель был переопределен, возможно, указан один пул потоков или использовался Executors.newSingleThreadExecutor();.

CompletableFuture:

Код CompletableFuture.runAsync{ new Runnable ()} создаст экземпляр CompletableFuture и выполнит код асинхронно (создаст поток) каждый раз, когда он вызывается.

CompletableFuture<Void> future
  = CompletableFuture.runAsync(() -> "This is processed asynchronously");
0 голосов
/ 20 декабря 2018

Как подчеркнул @ M.Deinum в своем комментарии, выполнение этого:

@Async("poolbeanname") 
Function () {
  CompletableFuture.runAsync{ new Runnable ()...} 
} 

Бесполезно, если оно вам действительно не нужно, потому что: @Async отправляет выполнение вашего метода в потоке poolbeannamepool и CompletableFuture.runAsync{ new Runnable ()...} создадут новый поток из вашего poolbeanname.

Вы можете просто сделать это:

@Async("poolbeanname") 
Function () {
  CompletableFuture.completedFuture( futureResult); 
} 

Обратите внимание, что из-за прокси объектов Spring, если вы сделаете это:

@Service
class YourService {

   callAsyncFunction(){
      function(); //@Async will not work here 
   }

   @Async("poolbeanname") 
   function () {
      CompletableFuture.completedFuture( futureResult);
    } 
}

Но вы можете использовать этот обходной путь:автоинъекция бобов.

@Service
class YourService {
   @Autowired
   @Lazy
   YourService  self;         

   callAsyncFunction(){
      self.function(); //@Async will work here 
   }

   @Async("poolbeanname") 
   function () {
      CompletableFuture.completedFuture( futureResult);
   } 
}
0 голосов
/ 20 декабря 2018

Чтобы включить использование @Async, вы должны использовать @ EnableAsync

Давайте начнем с включения асинхронной обработки с конфигурацией Java - просто добавив @EnableAsync в класс конфигурации:

@Configuration
@EnableAsync
public class SpringAsyncConfig { ... }

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

@ Async имеет два ограничения:

  • он должен применяться только к публичным методам

  • самовывоз - вызов асинхронного метода из того же класса - не будет работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...