您好,欢迎访问一九零五行业门户网

java中@Async异步调用的方法

前言异步调用与同步调用
同步调用:顺序执行,通过调用返回结果再次执行下一个调用
异步调用:通过调用,无需等待返回结果,执行下一个调用
1. @async讲解其@async的注解代码如下:
@target({elementtype.type, elementtype.method})@retention(retentionpolicy.runtime)@documentedpublic @interface async { string value() default "";}
注解可以使用在类型以及方法中
通过value定义其值,默认是空
一般这个注解需要配合@enableasync,起源码如下
@target({elementtype.type})@retention(retentionpolicy.runtime)@documented@import({asyncconfigurationselector.class})public @interface enableasync { class<? extends annotation> annotation() default annotation.class; boolean proxytargetclass() default false; advicemode mode() default advicemode.proxy; int order() default integer.max_value;}
主要通过该注解放置在启动类中进行配置启动
在启动类中添加如下:
@springbootapplication@enableasyncpublic class application{ public static void main(string[] args){ srpingapplication.run(application.class, args); }}

2. 用法2.1 同步调用从调用到返回函数结果才能执行下一步,称为同步调用
service层 代码:
public class service{ public void test01() throws interruptedexception{ thread.sleep(5000); system.out.println("保存日志"); }}
控制层代码模块:
public class controler{ @autowired private service service; @getmapping("/test") public string gettest(){ try{ system.out.println("开始"); service.test01(); system.out.println("结束"); }catch(interruptedexception e){ e.prinstacktrace(); } } }

通过springboot的启动类启动之后
输出如下:
开始
// 此为等待5秒钟,终端不显示也不关闭
结束
2.2 异步调用异步调用,执行函数不用等返回结果就可以执行下一步
service层 代码:
主要是添加了@async注解标识这个方法
public class service{ @async public void test01() throws interruptedexception{ thread.sleep(500); system.out.println("保存日志"); }}
控制层代码模块:
通过调用service层函数
public class controler{ @autowired private service service; @getmapping("/test") public string gettest(){ try{ system.out.println("开始"); service.test01(); system.out.println("结束"); }catch(interruptedexception e){ e.prinstacktrace(); } } }

以及在启动类中加入注解启动 @enableasync
@springbootapplication@enableasyncpublic class application{ public static void main(string[] args){ srpingapplication.run(application.class, args); }}

3. 自定义线程池对于线程池的一些基本知识可看我之前的文章:
java如何正确关闭线程以及线程池(代码实践含源码分析)
java线程池的创建方式详细分析(全)
如果不指定线程池,默认使用的线程池为simpleasynctaskexecutor(来一个任务就创建一个线程,不断创建线程导致cpu过高引发oom),自带的线程池一般都有弊端,一般推荐使用threadpoolexecutor(明确线程池的资源,规避风险)
具体如下:
newfixedthreadpool:定死了线程数,任务队列还是无界的,(最大线程数只有队列满了,最大线程数才会创建),所以会造成oom
newcachedthreadpool:没有设置最大线程数上限,创建大量的线程容易卡顿或者直接oom
通过自定义线程池可以调整线程池的配置,更好的资源利用
@async这个注解查找 asyncconfigurer接口(实现类为asyncconfigurersupport,默认配置和方法都是空),所以可重写接口指定线程池。
通过实现接口asyncconfigurer
继承asyncconfigurersupport
自定义taskexecutor(替代内置任务执行器)
第三种方法:
在application.xml中定义线程池的一些变量
thread.core.size=16thread.max.size=16thread.queue.size=30thread.prefix=xx-
自定义线程池如下
import org.springframework.beans.factory.annotation.value;import org.springframework.context.annotation.bean;import org.springframework.context.annotation.configuration;import org.springframework.scheduling.concurrent.threadpooltaskexecutor;import java.util.concurrent.threadpoolexecutor;@configurationpublic class threadpoolconfig { // 线程名称前缀 @value("${thread.prefix}") private string threadprefix; // 核心线程数 @value("${thread.core.size}") private int coresize; // 最大线程数 @value("${thread.max.size}") private int maxsize; // 队列长度 @value("${thread.queue.size}") private int queuesize; // 通过bean注解注入 @bean("xx") public threadpooltaskexecutor taskexecutor() { threadpooltaskexecutor taskexecutor = new threadpooltaskexecutor(); //设置线程池参数信息 taskexecutor.setcorepoolsize(coresize); taskexecutor.setmaxpoolsize(maxsize); taskexecutor.setqueuecapacity(queuesize); taskexecutor.setthreadnameprefix(threadprefix); taskexecutor.setwaitfortaskstocompleteonshutdown(true); taskexecutor.setawaitterminationseconds(30); //修改拒绝策略为使用当前线程执行 taskexecutor.setrejectedexecutionhandler(new threadpoolexecutor.callerrunspolicy()); //初始化线程池 taskexecutor.initialize(); return taskexecutor; }}
以上就是java中@async异步调用的方法的详细内容。
其它类似信息

推荐信息