@ Async is what
void test(a) {
A();
B();
C();
}
Copy the code
In the absence of Async, the above methods are executed sequentially and can also be called synchronous calls. B needs to be executed after A, C needs to be executed after B, and the whole function ends after C.
But if you add @async to B, the order of execution remains the same. After executing A, B is called and C is executed without waiting for B to complete. After executing C, the function is finished.
In Java, when dealing with similar scenarios, it is based on the creation of a separate thread to complete the corresponding asynchronous call logic, through the main thread and the execution flow between different threads, so that after starting the independent thread, the main thread continues to execute without the situation of stagnation.
When do I need to add @async
Depending on your business needs, you can set @async to a method that does not need to get processing for the time being.
For example, a user clicks on the front end to complete the login operation. In this case, according to service requirements, a buried point is processed after the successful login.
In fact, the success of embedding does not affect the user operation, in this case, you can set the embedding method to @async.
In my opinion, these tasks usually have three characteristics:
- The service priority is low.
- Running time is long and may cause lag.
- Results returned are not being processed immediately, including exceptions.
How do I use @async
- Add @enableAsync to the current Application or Config to let Spring know that Async is enabled.
@EnableAsync
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); }}Copy the code
- Add Async to the current method
@Async
public void B(a) {}Copy the code
- Matters needing attention
Static method modifiers are not valid! The call and the decorated method cannot be written in the same function.
Such as:
class Test {
public void A(a) {
B(); // Async will not be triggered
}
@Async
public void B(a) {}}Copy the code
So you need to break down the call:
class Test {
public void A(a) {
TestB testB = newTestB(); testB.B(); }}class TestB {
@Async
public void B(a) {}}Copy the code
- The return value can only be Future or Void, the way Future is used.
@Async
public Future<String> asyncMethod(a) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// Set the date format
System.out.println("StartTime - " + Thread.currentThread().getName() + df.format(new Date()));
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("EndTime - " + Thread.currentThread().getName() + df.format(new Date()));
return new AsyncResult<String>("hello world!");
}
@Test
public void contextLoads(a) {
Future<String> result1 = test.asyncMethod();
Future<String> result2 = test.asyncMethod();
Future<String> result3 = test.asyncMethod();
while(! result1.isDone() || ! result2.isDone() || ! result3.isDone()) {try {
Thread.sleep(1000);
} catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code
Custom thread pools
@Configuration
public class TaskConfiguration {
@Bean("taskExecutor")
public Executor taskExecutor(a) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // The number of threads initialized when the thread pool was created
executor.setMaxPoolSize(20); // The maximum number of threads in the pool. Only after the buffer queue is full will more threads than the number of core threads be applied
executor.setQueueCapacity(200); // The size of the buffer task queue
executor.setKeepAliveSeconds(60); // Allow thread idle time, which will be destroyed
executor.setThreadNamePrefix("custom-prefix-");// The thread prefix
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // The processing policy for rejecting tasks
returnexecutor; }}// After definition specified in Async
@Async("taskExecutor").Copy the code
Because the asynchronous task is still running when the application is shut down, objects such as the database connection pool are destroyed, and an error occurs when the database is operated on in the asynchronous task.
setWaitForTasksToCompleteOnShutdown(true): This method is used to set up the thread pool shutdown to wait for all tasks to complete before continuing to destroy other beans, so that the destruction of these asynchronous tasks precedes the destruction of database connection pool objects. SetAwaitTerminationSeconds (60) : this method is used to set the thread pool task waiting time, if more than this time haven’t destroy force to destroy, to ensure that the application of the last to be closed, and not blocked.