Use @Async annotation in Spring to implement asynchronous call

Asynchronous call?

    Before explaining the asynchronous call, let's look at the definition of synchronous call; synchronization is the sequential execution of the entire processing process, when each process is executed, and returns the result. The asynchronous call just sends the calling instruction, and the caller does not need to wait for the called method to be completely executed, and continues to execute the following process. For example, in a call, the three process methods A, B, and C need to be called in sequence ; if they are all synchronous calls, they need to be executed in sequence before the process is completed; if B is an asynchronous call method, after executing a later call B , does not wait for B to complete, but the execution start calling C , until C after finished, it means that the completion of the implementation process.

Overview Instructions

Spring by task executor (TaskExecutor) to implement multithreading and concurrent programming. Use ThreadPoolTaskExecutor to implement a TaskExcutor based on a thread pool . In actual development, the task is generally asynchronous. We can enable support for asynchronous tasks through @EnableAsync in the configuration class , and declare it to be an asynchronous task by using the @Async annotation in the method of the actually executed Bean .

Since Spring3, the @Async annotation is provided, which can be marked on the method to call the method asynchronously. The caller will return the result flag when calling, and the actual execution of the method will be submitted to the Spring TaskExecutor task, which will be executed by the thread in the specified thread pool.

@Async application custom thread pool

Configuration class

/**
 * @author 佛大Java程序员
 * @since 1.0.0
 */
@Configuration
@ComponentScan("com.whl.asyncdemo")
@EnableAsync
public class TaskExecutorConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setQueueCapacity(25);
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

Description:

* Use @EnableAsync comment open support asynchronous tasks
* need to define a custom thread pool configuration classes implement the interface and override AsyncConfigurer getAsyncExecutor (), returns a ThreadPoolTaskExecutor, so we get a thread pool based TaskExecutor

Executive class

/ ** 
 * @author 佛 大
    JavaProgrammer 
 * @since 1.0.0
  * / 
@Service 
public  class AsyncTaskService { 
@Async 
    public  void executeAsyncTask (Integer i) { 
        System.out.println ( "Execute asynchronous task 1:" + i ); 
    } 

    @Async 
    public  void executeAsyncTaskPlus (Integer i) { 
        System.out.println ( "Execute asynchronous task 2" + (i + 1 )); 
    } 
}

Explanation:

The @Async annotation indicates that the method is an asynchronous method. If the annotation is at the class level, it means that all methods in this class are asynchronous methods, and the methods here are automatically injected using ThreadPoolTaskExecutor as TaskExecutor.

Test class

/ ** 
 * @author 佛 大Javacoder 
 * @since 1.0.0
  * / 
public  class Main { 

    public  static  void main (String [] args) { 

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext (TaskExecutorConfig. class ); 
        AsyncTaskService asyncTaskService = context. getBean (AsyncTaskService. class ); 

        for ( int i = 0; i <5; i ++ ) { 
            asyncTaskService.executeAsyncTask (i); 
            asyncTaskService.executeAsyncTaskPlus(i);
        } 

        // Check whether the asynchronous method returns the result value first 
        System.out.println ("Return to successful execution, verify whether asynchronous returns the result value first" ); 
        context.close (); 

    } 
}

Results of the

Note @Async

Let go of the @Async annotation

 

@Async application default thread pool

 To be added

Transaction processing mechanism in @Async call ?

   The method annotated in @Async is also annotated with @Transactional ; when it invokes a database operation, it cannot generate transaction management control because the operation is based on asynchronous processing. How do you add transaction management to these operations? You can put methods that require transaction management operations inside asynchronous methods, and add @Transactional to the methods that are called internally .

(1)    Use the @ Async / @ Transactional be marked, but not the purpose of generating transaction control.

(2)    using the @Async to mark,  B called the C , D , C / D were used @Transactional purpose of labeling, the transaction control can be realized.

Project combat

The WKD project uses Easypoi technology to export Excel. When the amount of exported data is not large, it is fine to use synchronous export. However, for large amounts of data and the need to export the data encapsulation business is more complicated, OOM or response timeout will occur. In order to solve this problem, it is implemented by asynchronously exporting with a thread pool.

 

 Reference / good article:

Books-Practical SpringBoot-Edited by Wang Yunfei

Guess you like

Origin www.cnblogs.com/liaowenhui/p/12735252.html