SpringBoot implements asynchronous tasks

1. Asynchronous and synchronous

Asynchronous (async) is relative to synchronization (sync). It is simple to understand that synchronization is serial, and asynchronous is parallel.

For example, A needs to get data from two nodes B and C

In the first way, A requests B, B returns data to A, and A then requests C to obtain data from C. This way is synchronization.

Another way, A asks B, does not wait for B to return the data, then requests C, and then waits for B and C to prepare the data before pushing it to A. A can also get the data of B and C. This is asynchronous.

Note that the second method B and C process A's request at the same time, which is more efficient than the first method, but this method has a limitation, that is, the data to be obtained from B and C cannot be Dependency. If C needs the data returned from B when obtaining the data of C, then the first method can only be used, first request B, get the data of B, and then request C.

To give a more straightforward example, abstract ordering food into a few steps

  • 1. Place an order, the time is ignored.
  • 2. Cooking in the restaurant, 10 minutes.
  • 3. Find the takeaway brother, 5 minutes. (This requires a series of very troublesome algorithms to figure out which brothers to notify, wait for the brother to accept the delivery, and then calculate the approximate arrival time, assuming 5 minutes)
  • 4. Delivery, 5 minutes.

Processing in synchronization mode, 1, 2, 3, 4 add up to 20 minutes.

However, there is no strict relationship between cooking in the restaurant and finding a takeaway guy. 2 and 3 can be performed at the same time, so it only takes 15 minutes to calculate.

 Asynchronous and synchronous are two processing methods. Synchronization is applicable to many scenarios, and the coding is simple and easy to understand. However, in some specific scenarios, asynchronous is much more efficient than synchronous.

2. Code implementation, springboot uses asynchronous tasks

1. Add annotation @EnableAsync to AsyncTaskApplication startup class // enable asynchronous

2. Implement the task class and inject it into spring

package com.frank;

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

import java.util.Date;
import java.util.concurrent.Future;

/**
 * @author 小石潭记
 * @date 2020/6/29 20:52
 * @Description: ${todo}
 */
@Component
public class AsyncTask {

    @Async
    public Future<String> execTaskA() throws InterruptedException {
        System.out.println("TaskA开始");
        long star = new Date().getTime();
        Thread.sleep(5000);
        long end = new Date().getTime();
        System.out.println("TaskA结束,耗时毫秒数:" + (end - star));
        return new AsyncResult<>("TaskA结束");
    }

    @Async
    public Future<String> execTaskB() throws InterruptedException {
        System.out.println("TaskB开始");
        long star = new Date().getTime();
        Thread.sleep(3000);
        long end = new Date().getTime();
        System.out.println("TaskB结束,耗时毫秒数:" + (end - star));
        return new AsyncResult<>("TaskB结束");
    }

    @Async
    public Future<String> execTaskC() throws InterruptedException {
        System.out.println("TaskC开始");
        long star = new Date().getTime();
        Thread.sleep(4000);
        long end = new Date().getTime();
        System.out.println("TaskC结束,耗时毫秒数:" + (end - star));
        return new AsyncResult<>("TaskC结束");
    }
}

3. Use unit tests

package com.frank;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.concurrent.Future;

@SpringBootTest
class AsyncTaskApplicationTests {

    @Autowired
    AsyncTask asyncTask;

    @Test
    public void testAsyncTask() throws InterruptedException {
        long star = new Date().getTime();
        System.out.println("任务开始,当前时间" +star );
        Future<String> taskA = asyncTask.execTaskA();
        Future<String> taskB = asyncTask.execTaskB();
        Future<String> taskC = asyncTask.execTaskC();

        //间隔一秒轮询 直到 A B C 全部完成
        while (true) {
            if (taskA.isDone() && taskB.isDone() && taskC.isDone()) {
                break;
            }
            Thread.sleep(1000);
        }

        long end = new Date().getTime();
        System.out.println("任务结束,当前时间" + end);
        System.out.println("总耗时:"+(end-star));
    }

}

Through asynchronous tasks, the total time is 6031ms

Turn off the comment on the startup class, test, the total time is 12003ms

By comparison, asynchrony takes less time.

 

references

Guess you like

Origin blog.csdn.net/qq_33371766/article/details/107028400