Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement method asynchronism with springboot @ Async annotations

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces springboot @ Async annotation how to achieve asynchronous method, the content is very detailed, interested friends can refer to, hope to be helpful to you.

@ Async annotations how to implement method asynchronism

When dealing with large quantities of data, the efficiency is very slow. So consider using multithreading.

At the beginning of their own handwritten set, using the thread pool to start a fixed number of threads to run batches. But later, the boss considered that the risk of handwriting was difficult to control, so he used the spring method.

There is no detailed introduction here, only a simple demo, can only use, do not understand the principle:

1. Annotations required by springboot's App class package com.xxx.xxx.xxx;import java.util.concurrent.ThreadPoolExecutor;import org.springframework.boot.web.support.SpringBootServletInitializer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.task.TaskExecutor;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;/** * function description: service producer startup class *

* *

* * @ version * @ author * @ since 1.8 * / @ Configuration@EnableAsyncpublic class Application extends SpringBootServletInitializer {@ Bean public TaskExecutor taskExecutor () {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor (); / / set the number of core threads executor.setCorePoolSize (5); / / set the maximum number of threads executor.setMaxPoolSize (60); / / set the queue capacity executor.setQueueCapacity (20) / / set thread active time (seconds) executor.setKeepAliveSeconds (60); / / set default thread name executor.setThreadNamePrefix ("what-"); / / set deny policy executor.setRejectedExecutionHandler (new ThreadPoolExecutor.CallerRunsPolicy ()); / / wait for all tasks to finish before closing thread pool executor.setWaitForTasksToCompleteOnShutdown (true); return executor }}

Springboot's App class, which is very simple, can use a lot of things.

Second, the annotation package com.xxx.xxx.service.impl; import java.util.concurrent.Future; import org.springframework.scheduling.annotation.Async;import org.springframework.scheduling.annotation.AsyncResult;import org.springframework.stereotype.Service; import com.xxx.xxx.service.XXXAsyncService of the service layer; @ Servicepublic class XXXAsyncServiceImpl implements XXXAsyncService {@ Async public Future rtn1 () throws Exception {/ / do something / / when there is a return value, you can return things like string,long. Return new AsyncResult (1);} @ Async public void rtn2 () throws Exception {/ / do something / / this may not return a value. 3. Call layer package com.xxx.xxx.controller; import java.util.concurrent.Future; import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController; import com.xxx.xxx.service.XXXAsyncService; @ RestController@RequestMapping (value= "/ xxx") public class XXXAsyncController {@ Autowired private XXXAsyncService xxxAsyncService / * the asynchronous method * / @ RequestMapping (value = "/ xxx") public void dodo () throws Exception {int threads = 10 new ArrayList / 10 threads List list = new ArrayList () is called here; the asynchronous method is called iteratively here (int I = 0 X I < threads; iThreads +). / / if there is a large amount of data, you can slice the data here, then call it in a loop and process the data in batches. Efficient and leveraged. List .add (xxxAsyncService.rtn1 ());} long count = 0; for (Future l: tsfCountList) {/ / when the asynchronous call needs to return values, you can put all the returned values into the list collection, and then handle them uniformly. The get () here is blocked, so the asynchronous method returns because it is needed and continues to execute. Count + = l.get ();} System.out.println ("number of calls:" + count);}}

These codes are all handwritten and recorded, so that when you use them later, you don't have to forget them and find them troublesome.

The use of asynchronous annotations @ Async and precautions the first step is to turn on asynchronous @ Configuration@EnableAsyncpublic class SpringAsyncConfig {...}

By default, @ EnableAsync detects Spring's @ Async comment and EJB 3.1 javax. EJB. Asynchronous; this option can also be used to detect other user-defined annotation types. (you can also annotate @ EnableAsync directly on the startup class of SpringBoot)

In Spring, the specified method is annotated with @ Async, which is executed asynchronously when called. If no thread pool is specified in the @ Async annotation, the default thread pool is used. The default thread pool is SimpleAsyncTaskExecutor.

The thread pool does not reuse threads, and every time a new task is submitted, the thread pool creates a new thread instance to execute the task. Here is the related code:

Protected void doExecute (Runnable task) {Thread thread = (this.threadFactory! = null? This.threadFactory.newThread (task): createThread (task); thread.start ();}

If you want to specify a thread pool, you can specify the Bean Name of the thread pool you want to use by specifying the value parameter in the @ Async annotation. Another way is to have a configuration class that implements the AsyncConfigurer interface or inherits its default adapter class AsyncConfigurerSupport, so that the @ Async annotated method uses the specified custom thread pool.

The @ Async annotation uses the default thread pool of springBoot, but we usually customize the thread pool (because it is flexible) and configure it in the following ways:

How to configure using xml files

Configure using Java code with @ Configuration (recommended)

The following shows the code to configure the thread to implement package com.deppon.ptos.load.config; import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor;import java.util.concurrent.ThreadPoolExecutor / * * @ Description: asynchronous thread management * @ Author: LYH * @ CreateDate: 2019-6-27 8:54 * @ Version: 1.0 * @ JDK: 1.8 * / @ Configuration@EnableAsync@Slf4jpublic class ExecutorConfig {@ Value ("${async.executor.thread.core_pool_size}") private int corePoolSize; @ Value ("${async.executor.thread.max_pool_size}") private int maxPoolSize @ Value ("${async.executor.thread.queue_capacity}") private int queueCapacity; @ Value ("${async.executor.thread.name.prefix}") private String namePrefix; @ Bean (name = "asyncServiceExecutor") public Executor asyncServiceExecutor () {log.info ("start asyncServiceExecutor"); ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor (); / / configure the number of core threads executor.setCorePoolSize (corePoolSize) / / configure the maximum number of threads executor.setMaxPoolSize (maxPoolSize); / / configure the queue size executor.setQueueCapacity (queueCapacity); / / configure the name prefix executor.setThreadNamePrefix (namePrefix) of threads in the thread pool / / rejection-policy: how to handle the new task when pool has reached max size / / CALLER_RUNS: instead of executing the task in the new thread, the caller's thread executes executor.setRejectedExecutionHandler (new ThreadPoolExecutor.CallerRunsPolicy ()); / / initializes executor.initialize (); return executor;}} package com.deppon.ptos.load.config Import lombok.extern.slf4j.Slf4j;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.stereotype.Component;import org.springframework.util.concurrent.ListenableFuture; import java.util.concurrent.Callable;import java.util.concurrent.Future;import java.util.concurrent.ThreadPoolExecutor / * * @ Description: print the execution of asynchronous threads using Callbale Future to return thread information * @ Author: 633805 LYH * @ CreateDate: 2019-6-27 8:59 * @ Version: 633805 * @ JDK: 1.8 * / @ Component@Slf4jpublic class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {private void showThreadPoolInfo (String prefix) {ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor (); if (null = = threadPoolExecutor) {return } log.info ("{}, {}, taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]", this.getThreadNamePrefix (), prefix, threadPoolExecutor.getTaskCount (), threadPoolExecutor.getCompletedTaskCount (), threadPoolExecutor.getActiveCount (), threadPoolExecutor.getQueue (). Size ()) } @ Override public void execute (Runnable task) {showThreadPoolInfo ("1.do execute"); super.execute (task);} @ Override public void execute (Runnable task, long startTimeout) {showThreadPoolInfo ("2.do execute"); super.execute (task, startTimeout);} @ Override public Future submit (Runnable task) {showThreadPoolInfo ("1.do submit") Return super.submit (task);} @ Override public Future submit (Callable task) {showThreadPoolInfo ("2.do submit"); return super.submit (task);} @ Override public ListenableFuture submitListenable (Runnable task) {showThreadPoolInfo ("1.do submitListenable"); return super.submitListenable (task);} @ Override public ListenableFuture submitListenable (Callable task) {showThreadPoolInfo ("2.do submitListenable") Return super.submitListenable (task);}}

Use:

@ Async ("asyncServiceExecutor")

At this point, asynchrony is turned on.

The following is mainly about the wrong ones.

Use of @ Async causes async to be unsuccessful

The @ Async will be invalidated in the following ways

Asynchronous methods are decorated with static

Asynchronous classes do not use @ Component annotations (or other annotations) so that spring cannot scan to asynchronous classes

An asynchronous method cannot be in the same class as the called asynchronous method

You need to use @ Autowired or @ Resource annotations in the class to inject automatically. You cannot manually new objects by yourself.

If you use the SpringBoot framework, you must add the @ EnableAsync annotation to the startup class

This is the end of the springboot @ Async annotation on how to implement method asynchronism. I hope the above content can be of some help and learn more. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report