• 技术文章 >Java >java教程

    Java异步任务实现及分析

    PHPzPHPz2023-04-22 20:49:06转载40

    一、什么是异步任务

    无论是生活中还是程序里,大体可以分为两种 : 同步和异步。

    同步:比如你去吃海底捞,你要先点锅底,再点菜,然后服务员上锅底,再上菜,最后你才能吃上菜,这一过程得按顺序来。

    异步任务:还是去吃海底捞,吃的人很多,你前面有很多人,你可能要排队,等到排到你才能再进入餐厅。但是如果中途你想去个厕所,怎么办,回来还得重新排队。于是就有了叫号,你先排队取号,然后你可以去按个摩,看个电影,做个 spa ,买杯奶茶 .... 。终于到你了,这时候会 通知 你排到了,然后你就能进去了。这个过程便是异步的。

    二、SpringBoot + Async

    一开始想着开一个线程池,把任务丢线程池里去完成。

    后来想起来 SpringBoot 有一个比较方便的 异步 框架 Async

    代码也很简单,只需要在需要异步执行的方法上加个 @Async ,SpringBoot 启动类上添加 @EnableAsync 即可

        @Async
        public void task() {
            // do something
        }

    三、踩坑日记

    代码虽然少,但是坑可不会随着代码量的减少而减少。

    为了方便起见,我本地搭了个 demo,直接上代码

    @RestController
    public class AsyncController {
        @Autowired
        private AsyncService asyncService;
    
        @GetMapping("/v1/say")
        public String sayV1() {
            asyncService.sayV1();
            return "success1";
        }
    
        @GetMapping("/v2/say")
        public String sayV2() {
            asyncService.sayV2();
            return "success2";
        }
    }
    @Service
    public class AsyncService {
        public void sayV1() {
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello world");
        }
    
        @Async
        public void sayV2() {
            try {
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello world");
        }
    }

    很简单的 demo,提供两个接口,/v1/say 和 /v2/say,一个同步执行,一个异步执行,通过 sleep 3 秒来模拟耗时的任务

    正常启动,没有任何问题,同步执行的等 3 秒,主线程才会返回,异步执行的立刻返回,等3 秒才会输出 helloworld

    但是,当我加上断点后,问题产生了。

    我先是在 打印 hello world 那行加上个断点,效果和原来的一样,只是打印前被阻塞了,但并不影响主线程的返回。

    java异步任务实例分析

    编辑

    但当我把断点加在方法进来的位置,发现 主线程居然被阻塞了!

    java异步任务实例分析

    编辑

    四、解决

    各种问题排查,@Async 没有生效,异步任务等待主线程返回,都没有找到有效的解决方法。

    后来经过一个同事提醒,会不会是 debug 功能阻塞的线程呢?

    抱着试一试的态度,我找到了 debug 这边的配置

    java异步任务实例分析

    编辑

    断点可以选择阻塞 jvm 或者是 阻塞当前线程,默认是阻塞 jvm。

    将 suspend 选择 Thread,便不会再阻塞主线程了

    以上就是Java异步任务实现及分析的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:亿速云,如有侵犯,请联系admin@php.cn删除
    专题推荐:Java
    上一篇:Java中switch语句的使用方法和示例 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • java中UDP怎么发送数据• Java方法如何定义与调用• Java操作pdf的工具类itext怎么处理• Java+Tomcat环境怎么部署及安装• java的SynchronousQueue是什么
    1/1

    PHP中文网