The words written in the front

Hello, long time no see. How are you?

Today I’m going to bring you a problem I have with my actual project.

Basically, the process is to call the interface, update a copy of the data returned by the interface to the local database, and then return it to the front end. Updating to the local database was originally done asynchronously.

National Day back home, the company called, the front turn a few seconds of the circle, and then countless data. After checking, Redis is out of order and can’t be used.

What do you mean?

The data requested from the interface is updated to the local database. There is a policy of putting the data into Redis first, comparing it, and updating it if it is inconsistent. Redis is not available, so all queries to the database, it will be very slow, the front-end request interface is generally 5s timeout.

If it is asynchronous, this problem will not occur.

So, let’s see, at the time, my code was clearly asynchronous, why didn’t it work?

@ Async is invalid

Let’s start with an example.

The Controller code is as follows:

@GetMapping("/invalid")
public String invalidAsyncExample(a) {
    iTestAsyncService.invalidAsyncExample();
    return "Test completed" + LocalDateTime.now().toString();
}
Copy the code

The Service code is as follows:

@Override
public void invalidAsyncExample(a) {
    log.info("The process - 1 - {}", Thread.currentThread().getId());
    invalidAsyncTask();
    log.info("The process - 3 - {}", Thread.currentThread().getId());
}
Copy the code

The Async code is as follows:

@Async
public void invalidAsyncTask(a) {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    log.info("The process - 2 - {}", Thread.currentThread().getId());
}
Copy the code

Execution Result:

The 2020-11-11 21:14:06. 13592-784 the INFO [nio - 8080 - exec - 1] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Process - 1-125 2020-11-11 21:14:08. 13592-785 the INFO [nio - 8080 - exec - 1] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Process the 2020-11-11-2-125 21:14:08. 785 INFO - 13592 [nio - 8080 - exec - 1] C.F.S.A.S.I MPL. TestAsyncServiceImpl: process - 3-125Copy the code

@async: Async: Async: Async: Async: Async: Async: Async: Async: Async: Async: Async: Async: Async

Take this such a question, search the answer on Baidu. At the same time, I also decided to read the source code of this piece. I want to see how this asynchrony actually works.

As you can see from reading the source code, Spring uses proxies to implement asynchrony by default.

What do you mean?

You can understand that the classes you call need to be proxied by Spring before they can be executed asynchronously.

In the example above, invalidAsyncTask(); The invoked method is explicit and does not require a proxy, so Spring cannot help you execute it asynchronously.

For source code analysis, I’ll come back later when I write my source code blog.

Asynchronous task with no return value

Well, first of all, I need to do @enableAsync

Controller:

@GetMapping("/no-value")
public String noValueAsyncExample(a) {
    iTestAsyncService.noValueAsyncExample();
    return "Test completed" + LocalDateTime.now().toString();
}
Copy the code

Service:

@Override
public void noValueAsyncExample(a) {
    log.info("The process - 1 - {}", Thread.currentThread().getId());
    iAsyncService.exampleTask();
    log.info("The process - 3 - {}", Thread.currentThread().getId());
}
Copy the code

Time-consuming tasks:

@Override
public void exampleTask(a) {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    log.info("Time-consuming task -2-{}", Thread.currentThread().getId());
}
Copy the code

Async:

@Override
@Async
public void exampleTask(a) {
    iTestAsyncService.exampleTask();
}
Copy the code

Note that since we are placing time-consuming tasks in the same service, we are creating a problem of loop dependency, requiring @Lazy.

Test results:

The 2020-11-11 22:32:50. 18888-019 the INFO [nio - 8080 - exec - 7] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Process - 1-131 2020-11-11 22:32:50. 18888-020 the INFO [nio - 8080 - exec - 7] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Process - 3-131 22:32:52 2020-11-11. 18888-021 the INFO/task - 9 C.F.S.A.S.I MPL. TestAsyncServiceImpl: time consuming task - 2-152Copy the code

An asynchronous task with a return value

It also requires @enableAsync

Controller:

@GetMapping("/value")
public int valueAsyncExample(a) {
    return iTestAsyncService.valueAsyncExample();
}
Copy the code

Service:

@Override
public int valueAsyncExample(a) {
    int result = 0;

    long startTime = System.currentTimeMillis();

    List<Future<Integer>> futureList = new ArrayList<>();

    for (int i = 0; i < 10; i++) {
        Future<Integer> future = iAsyncService.addTask(i);
        futureList.add(future);
    }

    for (Future<Integer> f : futureList) {
        Integer value = null;
        try {
            value = f.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        if(value ! =null)
            result += value;
    }

    long endTime = System.currentTimeMillis();

    log.info("Time {} s", (endTime - startTime) / 1000D);

    return result;
}
Copy the code

Task:

@Override
public Future<Integer> addTask(int n) {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    log.info("Computing tasks -{}", Thread.currentThread().getId());
    return AsyncResult.forValue(n + 2);
}
Copy the code

Async:

@Override
@Async
public Future<Integer> addTask(int i) {
    return iTestAsyncService.addTask(i);
}
Copy the code

Again, note that because we are placing time-consuming tasks in the same service, we are creating a problem of loop dependency, requiring @Lazy.

Test results:

The 2020-11-11 22:27:05. 18888-152 the INFO [task - 3] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-146-2020-11-11. 18888-152 the INFO/task - 5 C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-148-2020-11-11. 18888-152 the INFO/task - 4 C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-147-2020-11-11. 18888-152 the INFO [task - 6] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-149-2020-11-11. 18888-153 the INFO/task - 7 C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-150-2020-11-11. 18888-152 the INFO/task - 2 C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-145-2020-11-11. 18888-153 the INFO [task - 8] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:05-151-2020-11-11. 18888-152 the INFO] [task - 1 C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:07-144-2020-11-11. 18888-154 the INFO [task - 6] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:07-149-2020-11-11. 18888-154 the INFO [task - 3] C.F.S.A.S.I MPL. TestAsyncServiceImpl: Computing tasks 22:27:07-146-2020-11-11. 18888-154 the INFO [nio - 8080 - exec - 1] C.F.S.A.S.I MPL. TestAsyncServiceImpl: takes 4.006 sCopy the code

The results page

65
Copy the code

The test code

Github.com/fengwenyi/s…