Como melhorar a performance no spring com multithreading

Trabalhar com multithreading em Spring Boot envolve o uso de threads paralelas para executar tarefas simultaneamente, o que pode melhorar a performance da aplicação, especialmente em operações de I/O, como acesso a bancos de dados ou chamadas a APIs externas.

Exemplo de implementação:

1. Usando o @Async para executar tarefas assíncronas

O Spring Boot fornece uma maneira simples de executar métodos de forma assíncrona com a anotação @Async. Primeiro, é necessário habilitar o suporte a assincronismo.

Passos:

  1. Habilitar o assincronismo: No arquivo de configuração principal (geralmente marcado com @SpringBootApplication), adicione a anotação @EnableAsync:

    @SpringBootApplication
    @EnableAsync
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
  2. Criar um método assíncrono: Em uma classe de serviço, você pode criar métodos que rodem em threads separadas usando a anotação @Async:

    @Service
    public class MyService {
     
        @Async
        public void executeAsyncTask() {
            System.out.println("Executando em thread: " + Thread.currentThread().getName());
            // Código que você deseja executar em paralelo
        }
    }
     
  3. Chamar o método: Quando você chama esse método, ele será executado em uma nova thread separada do fluxo principal:

     
    @RestController
    public class MyController {
     
        private final MyService myService;
     
        public MyController(MyService myService) {
            this.myService = myService;
        }
     
        @GetMapping("/runAsync")
        public String runAsyncTask() {
            myService.executeAsyncTask();
            return "Tarefa assíncrona iniciada!";
        }
    }
     

2. Customizar o Executor de Threads

Por padrão, o Spring Boot usa um SimpleAsyncTaskExecutor, mas é possível personalizar o pool de threads para melhor controlar a execução paralela.

Passos para configurar um ThreadPoolTaskExecutor:

  1. Configurar um Executor customizado:

    @Configuration
    public class AsyncConfig {
     
        @Bean(name = "taskExecutor")
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(10);
            executor.setQueueCapacity(100);
            executor.setThreadNamePrefix("Async-");
            executor.initialize();
            return executor;
        }
    }
     

    Aqui, você configura o número de threads mínimas e máximas e a capacidade da fila.

  2. Associar o Executor ao método assíncrono:

    Quando você quer que o método @Async use o executor customizado:

    @Async("taskExecutor")
    public void executeAsyncTask() {
        // Código assíncrono
    }
     

3. Usando CompletableFuture para lidar com retorno assíncrono

Quando você deseja que o método assíncrono retorne um valor, pode usar CompletableFuture.

 
@Async
public CompletableFuture<String> process() {
    // Simula uma tarefa demorada
    Thread.sleep(2000);
    return CompletableFuture.completedFuture("Processamento finalizado!");
}
 

Conclusão

O multithreading no Spring Boot é flexível e pode ser implementado com @Async para tarefas simples ou com executores customizados para cenários mais avançados. O uso de CompletableFuture também permite lidar com retornos de métodos assíncronos de forma eficiente.