Create Asynchronous Methods with Spring Boots

Source code : https://bitbucket.org/zengcode/async-method

มาสร้าง pom.xml กันก่อนครับ

<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework</groupId>
<artifactId>async-method</artifactId>
<version>0.1.0</version>

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

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

ใน main() ให้ enable Async และ Scheduler นะครับ เราจะให้ Scheduler เรียกใช้ Async Method กันในตัวอย่างนี้ สร้าง ThreadPoolExecutor เพื่อจัดการกับ Pool size ในการรัน Async Method ด้วยนะครับ

@SpringBootApplication
@EnableScheduling
@EnableAsync
public class AsyncMethodApplication extends AsyncConfigurerSupport {

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

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("zengcode-");
executor.initialize();
return executor;
}

}

สร้าง pain old java เพื่อทำงานใน Async Method ครับ

package websocket.zengcode.com.model;


public class Data {
private String value;

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

สร้าง Async Service เพื่อสร้าง Async Method ครับ เราจะ ทำการ delay นิดหน่อยเพื่อให้เห็นเวลาที่ชัดเจนนะครับ

@Service
public class AsyncService {

@Async
public Future<Data> getMessage() throws InterruptedException {

Thread.sleep(1000L);
Data data = new Data();
data.setValue(UUID.randomUUID().toString());
return new AsyncResult<>(data);
}
}

แล้วก็สร้าง SchedulerTask เพื่อเรียกใช้ Async Method

@Component
public class SchedulerTask {

private static Logger log = LoggerFactory.getLogger(SchedulerTask.class);

@Autowired
private AsyncService asyncService;

@Scheduled(fixedRate = 10000)
public void executingScheduler() throws InterruptedException, ExecutionException {
Instant start = Instant.now();

Future<Data> str1 = asyncService.getMessage();
Future<Data> str2 = asyncService.getMessage();
Future<Data> str3 = asyncService.getMessage();
Future<Data> str4 = asyncService.getMessage();
Future<Data> str5 = asyncService.getMessage();

while (!(str1.isDone() && str2.isDone() && str3.isDone() && str4.isDone() && str5.isDone())) {
Thread.sleep(10); //10-millisecond pause between each check
}


Instant end = Instant.now();
log.info("total execution times ========> " + ChronoUnit.MILLIS.between(start, end));
log.info("str1 = {} ", str1.get().getValue());
log.info("str2 = {} ", str2.get().getValue());
log.info("str3 = {} ", str3.get().getValue());
log.info("str4 = {} ", str4.get().getValue());
log.info("str5 = {} ", str5.get().getValue());
log.info("=====================================");
log.info("=====================================");
}

}

ซึ่งถ้าเราไม่ทำ Async Method เวลาในการทำงานก็จะประมาณ 5 sec แต่เมื่อใช้ Asyn Method มันจะทำงานพร้อมๆ กัน เวลาในการทำงานก็จะประมาณ 1 sec ครับผม

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.