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…