Java中如何实现异步调用

Java中如何实现异步调用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

@Test一、创建线程

Java中如何实现异步调用

publicvoidtest0()throwsException{
System.out.println("main函数开始执行");
Threadthread=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("===taskstart===");
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("===taskfinish===");
}
});
thread.start();
System.out.println("main函数执行结束");
}

二、Future

jdk8之前的实现方式,在JUC下增加了Future,从字面意思理解就是未来的意思,但使用起来却着实有点鸡肋,并不能实现真正意义上的异步,获取结果时需要阻塞线程,或者不断轮询。

@Test
publicvoidtest1()throwsException{
System.out.println("main函数开始执行");
ExecutorServiceexecutor=Executors.newFixedThreadPool(1);
Future<Integer>future=executor.submit(newCallable<Integer>(){
@Override
publicIntegercall()throwsException{
System.out.println("===taskstart===");
Thread.sleep(5000);
System.out.println("===taskfinish===");
return3;
}
});
//这里需要返回值时会阻塞主线程,如果不需要返回值使用是OK的。倒也还能接收
//Integerresult=future.get();
System.out.println("main函数执行结束");
System.in.read();
}

三、CompletableFuture

使用原生的CompletableFuture实现异步操作,加上对lambda的支持,可以说实现异步任务已经发挥到了极致。

@Test
publicvoidtest2()throwsException{
System.out.println("main函数开始执行");
ExecutorServiceexecutor=Executors.newFixedThreadPool(2);
CompletableFuture<Integer>future=CompletableFuture.supplyAsync(newSupplier<Integer>(){
@Override
publicIntegerget(){
System.out.println("===taskstart===");
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("===taskfinish===");
return3;
}
},executor);
future.thenAccept(e->System.out.println(e));
System.out.println("main函数执行结束");
}

四、Spring的Async注解

使用spring实现异步需要开启注解,可以使用xml方式或者Java config的方式。

xml方式:

<task:annotation-drivenexecutor="executor"/>
<task:executorid="executor"
pool-size="2"线程池的大小
queue-capacity="100"排队队列长度
keep-alive="120"线程保活时间(单位秒)
rejection-policy="CALLER_RUNS"对拒绝的任务处理策略/>

java方式:

@EnableAsync
publicclassMyConfig{
@Bean
publicTaskExecutorexecutor(){
ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();
executor.setCorePoolSize(10);//核心线程数
executor.setMaxPoolSize(20);//最大线程数
executor.setQueueCapacity(1000);//队列大小
executor.setKeepAliveSeconds(300);//线程最大空闲时间
executor.setThreadNamePrefix("fsx-Executor-");//指定用于新创建的线程名称的前缀。
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
returnexecutor;
}
}

(1)@Async

@Test
publicvoidtest3()throwsException{
System.out.println("main函数开始执行");
myService.longtime();
System.out.println("main函数执行结束");
}
@Async
publicvoidlongtime(){
System.out.println("我在执行一项耗时任务");
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("完成");
}

(2)AsyncResult

如果需要返回值,耗时方法返回值用AsyncResult包装。

@Test
publicvoidtest4()throwsException{
System.out.println("main函数开始执行");
Futurefuture=myService.longtime2();
System.out.println("main函数执行结束");
System.out.println("异步执行结果:"+future.get());
}
@Async
publicFuturelongtime2(){
System.out.println("我在执行一项耗时任务");
try{
Thread.sleep(8000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("完成");
returnnewAsyncResult<>(3);
}

看完上述内容,你们掌握Java中如何实现异步调用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!

发布于 2021-07-24 22:38:23
收藏
分享
海报
0 条评论
168
上一篇:iOS中怎么实现一个序列动画 下一篇:jvm中怎么加载一个类
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码