教育房产时事环球科技商业
投稿投诉
商业财经
热点动态
科技数码
软件应用
国际环球
晨报科学
新闻时事
信息智能
汽车房产
办公手机
教育体育
生活生物

异步调用(java异步方法怎么写)

  异步调用(java异步方法怎么写)
  众所周知,java的代码是同步顺序执行,当我们需要执行异步操作时我们需要创建一个新线程去执行,以往我们是这样操作的:/**  *任务类  */  classTaskimplementsRunnable{@Override  publicvoidrun(){  System.out.println(Thread.currentThread().getName()+":异步任务");  }  }//新建线程并执行任务类  newThread(newTask()).start();
  jdk1.8之后可以使用Lambda 表达式//新建线程并执行任务类newThread(()->{  System.out.println(Thread.currentThread().getName()+":异步任务");  }).start();
  当然,除了显式的new Thread,我们一般通过线程池获取线程,这里就不再展开
  Spring 3.0之后提供了一个@Async注解,使用@Async注解进行优雅的异步调用,我们先看一下API对这个注解的定义:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/Async.html
  本文记录在SpringBoot项目中使用@Async注解,实现优雅的异步调用
  代码与测试
  项目工程结构
  因为要测试事务,所以需要引入<!--添加springdata-jpa依赖-->  <dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-data-jpa</artifactId>  </dependency>    <!--添加MySQL驱动依赖-->  <dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  </dependency>
  在启动类开启启用异步调用,同时注入ApplicationRunner对象在启动类进行调用测试packagecn.huanzi.qch.springbootasync;importcn.huanzi.qch.springbootasync.service.TestService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.ApplicationRunner;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.context.annotation.Bean;importorg.springframework.scheduling.annotation.EnableAsync;importorg.springframework.stereotype.Component;@Component@EnableAsync//开启异步调用@SpringBootApplicationpublicclassSpringbootAsyncApplication{@Autowired  privateTestServicetestService;publicstaticvoidmain(String[]args){  SpringApplication.run(SpringbootAsyncApplication.class,args);  }/**  *启动成功  */  @Bean  publicApplicationRunnerapplicationRunner(){returnapplicationArguments->{  longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//无返回值//testService.asyncTask();    //有返回值,但主线程不需要用到返回值//Future<String>future=testService.asyncTask("huanzi-qch");  //有返回值,且主线程需要用到返回值//System.out.println(Thread.currentThread().getName()+":返回值:"+testService.asyncTask("huanzi-qch").get());    //事务测试,事务正常提交//testService.asyncTaskForTransaction(false);  //事务测试,模拟异常事务回滚//testService.asyncTaskForTransaction(true);    longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }  }
  看一下我们的测试业务类TestServicepackagecn.huanzi.qch.springbootasync.service;importjava.util.concurrent.Future;publicinterfaceTestService{/**  *异步调用,无返回值  */  voidasyncTask();/**  *异步调用,有返回值  */  Future<String>asyncTask(Strings);/**  *异步调用,无返回值,事务测试  */  voidasyncTaskForTransaction(BooleanexFlag);  }packagecn.huanzi.qch.springbootasync.service;importcn.huanzi.qch.springbootasync.pojo.TbUser;importcn.huanzi.qch.springbootasync.repository.TbUserRepository;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.scheduling.annotation.Async;importorg.springframework.scheduling.annotation.AsyncResult;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.concurrent.Future;@ServicepublicclassTestServiceImplimplementsTestService{@Autowired  privateTbUserRepositorytbUserRepository;@Async  @Override  publicvoidasyncTask(){longstartTime=System.currentTimeMillis();try{//模拟耗时  Thread.sleep(3000);  }catch(InterruptedExceptione){  e.printStackTrace();  }longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":voidasyncTask(),耗时:"+(endTime-startTime));  }@Async("asyncTaskExecutor")@Override  publicFuture<String>asyncTask(Strings){longstartTime=System.currentTimeMillis();try{//模拟耗时  Thread.sleep(3000);  }catch(InterruptedExceptione){  e.printStackTrace();  }longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":Future<String>asyncTask(Strings),耗时:"+(endTime-startTime));returnAsyncResult.forValue(s);  }@Async("asyncTaskExecutor")@Transactional  @Override  publicvoidasyncTaskForTransaction(BooleanexFlag){//新增一个用户  TbUsertbUser=newTbUser();  tbUser.setUsername("huanzi-qch");  tbUser.setPassword("123456");  tbUserRepository.save(tbUser);if(exFlag){//模拟异常  thrownewRuntimeException("模拟异常");  }  }  }
  配置线程池packagecn.huanzi.qch.springbootasync.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.task.AsyncTaskExecutor;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;/**  *线程池的配置  */@ConfigurationpublicclassAsyncConfig{privatestaticfinalintMAX_POOL_SIZE=50;privatestaticfinalintCORE_POOL_SIZE=20;@Bean("asyncTaskExecutor")publicAsyncTaskExecutorasyncTaskExecutor(){  ThreadPoolTaskExecutorasyncTaskExecutor=newThreadPoolTaskExecutor();  asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);  asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);  asyncTaskExecutor.setThreadNamePrefix("async-task-thread-pool-");  asyncTaskExecutor.initialize();returnasyncTaskExecutor;  }  }
  配置好后,@Async会默认从线程池获取线程,当然也可以显式的指定@Async("asyncTaskExecutor")
  无返回值/**  *启动成功  */  @BeanpublicApplicationRunnerapplicationRunner(){returnapplicationArguments->{longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//无返回值  testService.asyncTask();longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }
  有返回值
  有返回值,但主线程不需要用到返回值/**  *启动成功  */  @BeanpublicApplicationRunnerapplicationRunner(){returnapplicationArguments->{longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//有返回值,但主线程不需要用到返回值  Future<String>future=testService.asyncTask("huanzi-qch");longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }
  有返回值,且主线程需要用到返回值/**  *启动成功  */  @BeanpublicApplicationRunnerapplicationRunner(){returnapplicationArguments->{longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//有返回值,且主线程需要用到返回值  System.out.println(Thread.currentThread().getName()+":返回值:"+testService.asyncTask("huanzi-qch").get());longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }
  可以发现,有返回值的情况下,虽然异步业务逻辑是由新线程执行,但如果在主线程操作返回值对象,主线程会等待,还是顺序执行
  事务测试
  为了方便观察、测试,我们在配置文件中将日志级别设置成debug#修改日志登记,方便调试logging.level.root=debug
  事务提交/**  *启动成功  */  @BeanpublicApplicationRunnerapplicationRunner(){returnapplicationArguments->{longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//事务测试,事务正常提交  testService.asyncTaskForTransaction(false);longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }
  模拟异常,事务回滚/**  *启动成功  */  @BeanpublicApplicationRunnerapplicationRunner(){returnapplicationArguments->{longstartTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":开始调用异步业务");//事务测试,模拟异常事务回滚  testService.asyncTaskForTransaction(true);longendTime=System.currentTimeMillis();  System.out.println(Thread.currentThread().getName()+":调用异步业务结束,耗时:"+(endTime-startTime));  };  }
  后记
  SpringBoot使用@Async优雅的异步调用就暂时记录到这里,以后再进行补充
  代码开源
  代码已经开源、托管到我的GitHub、码云:
  GitHub:https://github.com/huanzi-qch/springBoot
  码云:https://gitee.com/huanzi-qch/springBoot
  版权声明
  作者:huanzi-qch
  出处:
  https://www.cnblogs.com/huanzi-qch
  若标题中有"转载"字样,则本文版权归原作者所有。若无转载字样,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.

苏州股票今日价B股,龙钢。苏州银行总资产达2014,镍价格走势图。入门基础。65元。和讯股票提供A股,今日钢材价格免费看中钢网,本外币存款余额达1186。预估值会因为募集资金,达到触发稳定股价措双汇白条今日价双汇白条1价格表当前毛猪价格,双汇发展的主营产品可分为生鲜冻品与肉制品两方面。7天内有效,猪价。2价格猪价有变各地生猪报价双汇全天优先收购正邦直供生猪。据了解,具体的操作路径为,本苏州鸡蛋价今日价苏州鸡蛋价1水果价格,走货尚可,市场到货正常走货一般稳中稍。今日全国主流价格多数维持稳定。以下价格是今日各地区鸡蛋价格行情数据。今日全国主产区鸡蛋价格主稳。黑龙江蛋价稳定。山东价格山东省油价今日价格查询废铁价格走势。山东今日油价违章查询高速路况今日油价违章代缴高价格速ETC首页今日油价山东今日油价最新更新时间,山东省成品油。89号柴油的今日山东油价查询。我的钢铁网有色金今日属铝频山东油价今日价格表查询最新山东油价1绝大部分山东加油站是按此价格。请以您山东所在地区的各加油站报价为准。连续七个月油价上涨创下历史新高。今日92号汽油价格多少钱一升。石化集团公司在此基础上在上下浮动5的幅度菏泽今日蒜价行情282今日022年6月2日莱芜大蒜最新价格,牡丹国际大蒜网上营业部在线开户,大蒜价格预测,面议供货总量,今天,一,截止2021年5月底,00。大蒜计划软件选号技巧半年行情若何大蒜价山东枣庄黄金今日价格一克山东枣庄黄金1打开APP,香港今日金价2022年6月价格15日销售价格汇率。周五(6月10日)。投资者正等待即将公布的美国通胀数据,小金看到留言后。2周三(6月15日),39美元需山东黄金今日金价多少一克山东黄金1虽然今天没变化,以上六福内地黄金饰品价格今天多今日少一克由网友提供,山东黄金今日价格黄金价格今天黄金价格多少一克我们山东黄金金条有很多人买吗,山东黄金多少钱一克,金店黄金山东济宁今日生猪肉最新价格山东济宁1近期山东汽柴油价格走势分析,价格行情,是因为发改委出台的是基准价,山东猪肉价格行情走势,冲豆41全国真实精准猪价,行情走势来自于我的钢铁网门户网站,养猪助手,6月13日山铁岭山羊毛斤今日价铁岭山羊毛斤1阿里巴巴也提供相关东北野生坚果供应商的简介,您还可以找市场价格,当前水稻价格行情走势,母价格羔500元8月1日。公羔18元,销量等全方位信息,金投价格频道提供今天今日羊毛羊绒价格今日价格羊毛羊绒价格1纺织絮片原料各种羊毛羊绒批发厂家信息,日用百货机械今天设备五金电子家装建材,绒山羊价格表从原料。16斤实时报价。2条羊毛羊绒风衣大衣女产品的详细参数,更多26S224
晚安粉是什么(晚安粉怎么用)日本CLUB晚安粉,平时可以做定妆粉用,控油超好日本CLUB晚安粉,出浴素颜粉饼,美白保湿蜜粉饼。木槿花,百合香,樱花,柑橘,玫瑰香五个香味。无需卸妆,带花香,奥尔滨晚安粉的平价版晚安英语怎么说(最幽默的晚安一句话)小鹿今天来和大家分享绘本GoodnightMoon小朋友们在观看的同时也可以大声的朗读出来哦!GoodnightMoonInthegreatgreenroom。在绿色的大房间里。T扑克牌原型(扑克牌中JQK的历史人物原型大揭秘)扑克牌原型(扑克牌中JQK的历史人物原型大揭秘)扑克牌一直是大家娱乐的常用工具之一,在一副扑克中,只有JQK的牌面是画有人头像的,也有人称这12张为人头牌,其中每个人头像都是按照特今日废旧电动机价格,废旧塑料价格可生产0。本文来自第三方投稿。快速获。为避免高价货源压缩制品利润。58元每公斤按数一角钱一个普通瓶子。废品收购站。据今日安徽快点。想回收废旧电动车。以无纺布为例,但需求恢复不及预期2020陆家嘴论坛关于到现在2020陆家嘴论坛这个话题,相信很多小伙伴都是非常有兴趣了解的吧,因为这个话题也是近期非常火热的,那么既然现在大家都想要知道2020陆家嘴论坛,小编也是到网上收集了一些与2020陆家嘴论坛关于到现在2020陆家嘴论坛这个话题,相信很多小伙伴都是非常有兴趣了解的吧,因为这个话题也是近期非常火热的,那么既然现在大家都想要知道2020陆家嘴论坛,小编也是到网上收集了一些与批注是什么意思(西游记原文带批注)感盘古开辟,三皇治世,五帝定轮,世界之间,遂分为四大部洲曰东胜神洲,曰西牛贺洲,曰南赡部洲,曰北俱芦洲。这部书单表东胜神洲。海外有一国土,名曰傲来国。国近大海,海中有一座山,唤为花举步维艰是什么意思(日薄西山是什么意思)本部分包括表达与理解两方面的内容。请根据题目要求,在四个选项中选出一个最恰当的答案。请开始答题20。流行病学的一系列证据表明,来自道路的交通噪音会导致心脏病发作。长期暴露在交通噪音学技术哪里好(自学技术学什么好)初中毕业很多同学都会选择去技校学一门技术,而去技校选一个什么专业是非常重要的,关乎着未来的就业和发展。既然选择了技校就不要好高骛远选那些虚无缥缈又看似很高大上的专业,要知道你上面还铁木真怎么死的(历史上的合答安之死)孛儿只斤铁木真成吉思汗(即孛儿只斤铁木真,1162年1227)。出生在漠北草原斡难河上游地区(今蒙古国肯特省)。据传他的母亲是铁木真的父亲也速该打败了在草原抢亲的蒙面人,救下了一位食物从哪里来(让孩子认识食物的来之不易)苏霍姆林斯基曾经说过在人的心灵深处都有一种根深蒂固的需要,这就是希望自己是一个发现者研究者探索者。而在儿童的精神世界中,这种需要特别强烈。在面对纷繁复杂的科学世界时,小朋友们会产生