Spring-boot actual Combat "10" "Go": Use @async to implement asynchronous calls in Spring boot

Source: Internet
Author: User

What is an "asynchronous call"?

"Asynchronous call" corresponds to "synchronous call", synchronous invocation refers to the program in the order of definition, each line of the program must wait for the last line of the program to execute before execution; asynchronous invocation refers to the program in order Executes the subsequent program without waiting for the statement of the asynchronous call to return the result.

Synchronous invocation

Here's a simple example to intuitively understand what a synchronous call is:

    • Define the task class, create three processing functions to simulate three execution of the task, the operation consumes time random (within 10 seconds)
123456789101112131415161718192021222324252627282930 @Componentpublic class Task { public static random random =new Random (); public void dotaskone() throws Exception { System.out.println ("Start doing task one");Long start = System.currenttimemillis ();Thread.Sleep (Random.nextint (10000));Long end = System.currenttimemillis ();System.out.println ("Complete task one, time-consuming:" + (End-start) + "milliseconds"); }public void dotasktwo() throws Exception { System.out.println ("Start doing task two");Long start = System.currenttimemillis ();Thread.Sleep (Random.nextint (10000));Long end = System.currenttimemillis ();System.out.println ("Complete task two, time-consuming:" + (End-start) + "milliseconds"); }public void dotaskthree() throws Exception { System.out.println ("Start doing task three");Long start = System.currenttimemillis ();Thread.Sleep (Random.nextint (10000));Long end = System.currenttimemillis ();System.out.println ("Complete task three, time-consuming:" + (End-start) + "milliseconds"); } }
    • In the unit test case, inject a task object and execute doTaskOne , doTaskTwo three functions in the test case doTaskThree .
123456789101112131415 @RunWith (Springjunit4classrunner.class) @SpringApplicationConfiguration (classes = application.class) public class applicationtests { @AutowiredPrivate task task; @Test public void Test() throws Exception {task.dotaskone (); Task.dotasktwo (); Task.dotaskthree ();} }
    • To perform unit tests, you can see output similar to the following:
123456 Start a task one complete task one, time: 4256 milliseconds to start the task two complete task two, time: 4957 milliseconds to start the task three complete task three, time: 7173 milliseconds

Task one, task two, task three the execution of the order is finished, in other words doTaskOne , doTaskTwo doTaskThree three function sequence execution is complete.

asynchronous invocation

The above-mentioned synchronous call, although successfully completed three tasks, but can see the execution time is relatively long, if there is no dependency between the three tasks themselves, can be executed concurrently, synchronous calls in the execution efficiency is poor, you can consider the asynchronous invocation of the way to execute concurrently.

In spring boot, we simply have to make the @Async original synchronization function into an asynchronous function by using annotations, and the task class is changed to the following pattern:

12345678910111213141516171819 @Componentpublic class Task { @Asyncpublic void dotaskone() throws Exception { ///IBID. content, omitted}@Asyncpublic void dotasktwo() throws Exception { ///IBID. content, omitted}@Asyncpublic void dotaskthree() throws Exception { ///IBID. content, omitted} }

In order for the @async annotation to take effect, you will also need to configure @enableasync in the main program of spring boot, as follows:

123456789 @SpringBootApplication @EnableAsync public class application { public static void main(string[] args) { springapplication.run (Application.class, args);} }

You can perform unit tests over and over again, and you may encounter a variety of different results, such as:

    • No task-related output
    • Some task-related outputs
    • Out-of-order task-related output

The reason is that the current doTaskOne , doTaskTwo doTaskThree Three functions have been executed asynchronously. After the main program is called asynchronously, the main program does not care whether the three functions are completed, and because there is nothing else to do, the program ends automatically, resulting in incomplete or no output task-related content.

Note: @Async the modified function is not defined as a static type, so the asynchronous call does not take effect

Asynchronous callbacks

In order doTaskOne to doTaskTwo doTaskThree be able to end normally, let's say we need to figure out how much time it takes for the three tasks to execute concurrently, and this will require you to wait until the above three functions have completed the transfer and then calculate the results.

So how do we tell if the above three asynchronous calls have been completed? We need to use it Future<T> to return the result of an asynchronous call, as in the following ways doTaskOne :

123456789 @Async Public future<string> dotaskone() throws Exception {System.out.println ( "Start doing task one"); Long start = System.currenttimemillis (); Thread.Sleep (Random.nextint (10000)); Long end = System.currenttimemillis (); System.out.println ("Complete task One, time consuming:" + (End-start) + "millisecond"); return new asyncresult<> ("task one completed");}

After transforming the other two async functions as described above, let's change the test case so that the test does something else after waiting for three asynchronous calls to complete.

12345678910111213141516171819202122 @Test public void test () throws Exception {  long start = System.currenttimemillis ();  Future<String> Task1 = Task.dotaskone (); future<string> Task2 = Task.dotasktwo (); future<string> task3 = Task.dotaskthree ()  while (true) { if (task1.isdone () && task2.isdone () && Task3.isdone ()) { //three tasks are called completion, exiting the loop waiting for break; } Thread.Sleep (1000); }  long end = System.currenttimemillis ();  system.out.println ( "task completed, total time elapsed:" + (End-start) + "milliseconds");  }

See what changes we've made:

    • Begin recording start time at the beginning of a test case
    • Returns the result object of a type when three asynchronous functions are called Future<String>
    • After three asynchronous functions are called, a loop is opened to Future<String> determine whether the three async functions are finished based on the returned object. If it ends, it ends the cycle, and if it is not, wait 1 seconds before judging.
    • After jumping out of the loop, the total time spent on the execution of three tasks is calculated based on the end-of-start time.

To perform the above unit tests, you can see the following results:

1234567 Start doing the task two start doing task three complete task three, time: 37 milliseconds to complete task two, time: 3661 milliseconds to complete task one, time: 7149 milliseconds task complete, total time: 8025 milliseconds

It can be seen that by asynchronous invocation, the task one and two or three are executed concurrently, effectively reducing the total running time of the program.

Complete Example Chapter4-1-2

Spring-boot actual Combat "10" "Go": Use @async to implement asynchronous calls in Spring boot

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.