Friday, 27 September 2019

Spring boot: Creating Asynchronous Methods Using @Async Annotation


Step 1: Enable Asynchronous support to the application.
@EnableAsync
@Configuration
public class AppConfiguration {
  ......
  ......
}


Step 2: Create ThreadPoolTaskExecutor bean.
@EnableAsync
@Configuration
public class AppConfiguration {

  private static final int NUMber_OF_PROCESSORS = Runtime.getRuntime().availableProcessors();

  @Bean("appThredPool")
  public Executor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
    threadPoolExecutor.setCorePoolSize(NUMber_OF_PROCESSORS * 5);
    threadPoolExecutor.setMaxPoolSize(NUMber_OF_PROCESSORS * 50);
    threadPoolExecutor.setThreadNamePrefix("BackGround_ThreadPool");
    threadPoolExecutor.initialize();
    return threadPoolExecutor;
  }

}

Step 3: Add @Async annotation to a method that you want to execute asynchronously.
@Async("appThredPool")
public CompletableFuture<String> welcomeUser() {
  System.out.println("Executing welcomeUser method");
  sleep(3);
  System.out.println("welcomeUser method finsihed");
  return CompletableFuture.completedFuture("Welcome User!!!!!!");
}


Step 4: You can call asynchronous methods like below
CompletableFuture<String> helloFuture = testUtil.sayHello();
CompletableFuture<String> welcomeFuture = testUtil.welcomeUser();

CompletableFuture.allOf(helloFuture, welcomeFuture).join();

join() method waits until all the completable futures are finished.

Find the below working application

AppConfiguration.java
package com.sample.app.config;

import java.util.concurrent.Executor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@EnableAsync
@Configuration
public class AppConfiguration {

  private static final int NUMber_OF_PROCESSORS = Runtime.getRuntime().availableProcessors();

  @Bean("appThredPool")
  public Executor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
    threadPoolExecutor.setCorePoolSize(NUMber_OF_PROCESSORS * 5);
    threadPoolExecutor.setMaxPoolSize(NUMber_OF_PROCESSORS * 50);
    threadPoolExecutor.setThreadNamePrefix("BackGround_ThreadPool");
    threadPoolExecutor.initialize();
    return threadPoolExecutor;
  }

}


TestUtil.java
package com.sample.app.util;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class TestUtil {

  private static void sleep(int n) {
    try {
      TimeUnit.SECONDS.sleep(n);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  @Async("appThredPool")
  public CompletableFuture<String> sayHello() {
    System.out.println("Executing sayHello method");
    sleep(3);
    System.out.println("sayHello method finsihed");
    return CompletableFuture.completedFuture("Hello User!!!!!!");
  }

  @Async("appThredPool")
  public CompletableFuture<String> welcomeUser() {
    System.out.println("Executing welcomeUser method");
    sleep(3);
    System.out.println("welcomeUser method finsihed");
    return CompletableFuture.completedFuture("Welcome User!!!!!!");
  }
}


App.java
package com.sample.app;

import java.util.concurrent.CompletableFuture;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.sample.app.util.TestUtil;

@SpringBootApplication
public class App {

  @Autowired
  private TestUtil testUtil;

  public static void main(String args[]) {
    SpringApplication.run(App.class, args);
  }

  @Bean
  public CommandLineRunner demo() {
    return (args) -> {
      CompletableFuture<String> helloFuture = testUtil.sayHello();
      CompletableFuture<String> welcomeFuture = testUtil.welcomeUser();

      CompletableFuture.allOf(helloFuture, welcomeFuture).join();

      System.out.println("**************************");
      System.out.println(helloFuture.get());
      System.out.println(welcomeFuture.get());
      System.out.println("**************************");
    };
  }
}


pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>springAsync</groupId>
  <artifactId>springAsync</artifactId>
  <version>1</version>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>

  </dependencies>
</project>


Total project structure looks like below.

Run App.java, you can see below messages in console.

Executing sayHello method
Executing welcomeUser method
welcomeUser method finsihed
sayHello method finsihed
**************************
Hello User!!!!!!
Welcome User!!!!!!
**************************

You can download working application from this link.





Previous                                                    Next                                                    Home

No comments:

Post a Comment