Spring Boot Part 23: Asynchronous Methods

This article mainly introduces the use of asynchronous methods in springboot to request github api.

Create project

Introduce the relevant dependencies in the pom file:

<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>

Create an entity that receives the data:

@JsonIgnoreProperties(ignoreUnknown=true)
public class User {

    private String name;
    private String blog;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBlog() {
        return blog;
    }

    public void setBlog(String blog) {
        this.blog = blog;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", blog=" + blog + "]";
    }

}

Create a requested github service:

@Service
public class GitHubLookupService {

    private static final Logger logger = LoggerFactory.getLogger(GitHubLookupService.class);

    private final RestTemplate restTemplate;

    public GitHubLookupService(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    @Async
    public Future<User> findUser(String user) throws InterruptedException {
        logger.info("Looking up " + user);
        String url = String.format("https://api.github.com/users/%s", user);
        User results = restTemplate.getForObject(url, User.class);
        // Artificial delay of 1s for demonstration purposes
        Thread.sleep(1000L);
        return new AsyncResult<>(results);
    }

}

Through, RestTemplate to request, plus the class @Async indicates that it is an asynchronous task.

Start asynchronous tasks:

@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {

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

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

}

Enable asynchronous tasks through @EnableAsync; and configure AsyncConfigurerSupport, for example, the maximum thread pool is 2.

test

The test code is as follows:

@Component
public class AppRunner implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);

    private final GitHubLookupService gitHubLookupService;

    public AppRunner(GitHubLookupService gitHubLookupService) {
        this.gitHubLookupService = gitHubLookupService;
    }

    @Override
    public void run(String... args) throws Exception {
        // Start the clock
        long start = System.currentTimeMillis();

        // Kick of multiple, asynchronous lookups
        Future<User> page1 = gitHubLookupService.findUser("PivotalSoftware");
        Future<User> page2 = gitHubLookupService.findUser("CloudFoundry");
        Future<User> page3 = gitHubLookupService.findUser("Spring-Projects");

        // Wait until they are all done
        while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
            Thread.sleep(10); //10-millisecond pause between each check
        }

        // Print results, including elapsed time
        logger.info("Elapsed time: " + (System.currentTimeMillis() - start));
        logger.info("--> " + page1.get());
        logger.info("--> " + page2.get());
        logger.info("--> " + page3.get());
    }

}

Start the program and the console will print:

2017-04-30 13:11:10.351 INFO 1511 —- [ GithubLookup-1] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware
2017-04-30 13:11:10.351 INFO 1511 —- [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up CloudFoundry
2017-04-30 13:11:13.144 INFO 1511 —- [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

Time spent: 3908

Analysis: The first two methods of the card can be executed in GithubLookup-1 and GithubLookup-2 respectively, and the third one is executed in GithubLookup-2. Note that the maximum thread is 2 when configuring the thread pool. If you put the number of thread pools When it is 3, the time-consuming is reduced.

If you remove @Async, you will find that all three methods are executed in the main thread. The time-consuming summary is as follows:

2017-04-30 13:13:00.934 INFO 1527 —- [ main] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware
2017-04-30 13:13:03.571 INFO 1527 —- [ main] com.forezp.service.GitHubLookupService : Looking up CloudFoundry
2017-04-30 13:13:04.865 INFO 1527 —- [ main] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

Time spent: 5261

Through this small chestnut, you should have a certain understanding of asynchronous tasks.

References

https://spring.io/guides/gs/async-method/

Source code download

https://github.com/forezp/SpringBootLearning

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324602805&siteId=291194637