java异步操作,java获取异步执行结果
00-1010前言1、什么是异步任务2、跳靴异步3、踩坑日记4、解决方案5、总结
00-1010最近在开发中遇到一个需要埋点的问题。考虑到不能影响原有的业务逻辑,我准备写一个异步任务来异步执行,但是在调试的过程中发现了一个奇怪的问题。
00-1010无论是生活中还是程序中,大致可以分为同步和异步两种。
同步:比如你去吃海底捞,你要先点锅底,再点,然后服务员上菜,最后你才能吃,才能上菜。这个过程必须按顺序进行。
异步任务:不如吃海底捞。吃的人很多。你前面有很多人。你可能不得不排队等候,直到你进入餐馆前排队。但是中途想上厕所,怎么办?回来又要排队了。于是就有了电话,你排队等着取号,然后就可以按个按摩,看个电影,泡个spa,买杯奶茶。最后,轮到你了。这个时候你会在通知,然后你就可以进去了。这个过程是异步的。
00-1010一开始我想着启动一个线程池,把任务扔进线程池完成。
后来想起来SpringBoot有一个方便的异步框架Async。
代码也很简单,只需要在需要异步执行的方法中添加@Async,在SpringBoot启动类中添加@EnableAsync即可。
@Async public void task() { //做点什么}
00-1010码少,但坑数不会随着码数的减少而减少。
为了方便,我在本地设置了一个演示,直接加载代码。
@ RestControllerpublic class async controller { @ auto wired private async service async service;@GetMapping(/v1/say )公共字符串say v1(){ async service . say v1();返回“成功1”;} @GetMapping(/v2/say )公共字符串say v2(){ async service . say v2();返回“成功2”;} } @ service public class async service { public void say v1(){ try { thread . sleep(3000 l);} catch(interrupted exception e){ e . printstacktrace();} system . out . println( hello world );} @ Async public void say v2(){ try { thread . sleep(3000 l);} catch(interrupted exception e){ e . printstacktrace();} system . out . println( hello world );}}非常简单的演示,提供了/v1/say和/v2/say两个接口,一个用于同步执行,一个用于异步执行,通过3秒睡眠模拟耗时任务。
正常启动,没有任何问题。主线程同步执行3秒就返回,异步执行就立即返回。它将在3秒钟后输出helloworld。
然而,当我添加断点时,问题出现了。
首先我在打印hello world的那一行加了一个断点,效果和原来一样,只是在打印之前被阻止了,但是不影响主线程的返回。
编辑
但是当我把断点加到方法进来的位置时,发现主线程居然被阻塞了!
编辑
00-1010排查各种问题,@Async没有生效,异步任务等待主线程返回,没有找到有效的解决方案。
后来有同事提醒后,会不会是调试功能阻塞的线程?
抱着试试看的态度,在调试端找到了配置。
编辑
断点可以选择阻塞jvm或者当前线程,默认是阻塞jvm。
选择suspend to Thread,主线程不会再被阻塞。
00-1010我们都是站在巨人的肩膀上编程,很多事情只知道他们的结果,却不知道为什么。debug是一个常用的函数,但是我们不知道它的真正原理。以后遇到问题,要多考虑它的原理。
这就是本文关于java异步任务的全部内容。有关java异步任务的更多信息,请搜索Popular IT以前的文章或继续浏览下面的相关文章。我希望你将来能支持流行它!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。