springboot单元测试丢失异步任务

今天在写单元测试时遇到一个问题,单元测试里调用异步函数,执行完毕后发现异步函数期望达成的结果和预期不一致,记录下分析过程。

Junit Test

@Test
void test(){
	//jvm关闭钩子函数
    //Runtime.getRuntime().addShutdownHook(new Thread(() -> log.info("钩子开始执行:{}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon())));
    log.info("{}-{}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
    Thread t = new Thread(()->{
        log.info("{}-{}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("子线程运行结束");
    });
    //关闭守护线程标记
    //t.setDaemon(false);
    t.start();
    log.info("MAIN线程运行结束");
}

执行结果:
从结果看在这里插入图片描述从执行结果看,我们期望的"子线程运行结束"描述未出现,说明异步任务丢失了,我们都知道java线程依赖jvm实例,这里线程“死亡了”,单元测试执行完毕等多久才会销毁jvm呢,接下来打开钩子函数
在这里插入图片描述确实看到钩子函数被立即执行了,并不会等子线程执行结束。
那jvm的销毁是否和守护线程、用户线程有关呢?答案是否定的,大家可以打开上面代码中“守护线程标记”做下实验,就不演示了。

接下来我们再试下main函数的情况

main函数模拟

public static void main(String[] args) {
	//jvm关闭钩子函数
    //Runtime.getRuntime().addShutdownHook(new Thread(() -> log.info("钩子开始执行:{}, {}", Thread.currentThread().getName(), Thread.currentThread().isDaemon())));
    log.info("main线程号:{},守护线程:{}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
    Thread t = new Thread(()->{
        log.info("sub线程号:{},守护线程:{}", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("子线程运行结束");
    });
    // 守护线程标记
    t.setDaemon(false);
    t.start();
    log.info("main线程运行结束");
}

执行结果
在这里插入图片描述看起来main函数执行完最后一行并没有影响子线程的执行,说明jvm实例销毁是在子线程执行完毕才进行的,我们打开钩子函数再次执行
在这里插入图片描述jvm的销毁是发生在函数所有任务全部执行完毕才进行的。
另外,我们知道当程序只有守护线程时,也就是说守护线程没有了待守护的用户线程,jvm会被立即销毁,那是否真的是这样呢?我们将子线程的守护线程属性设置为true,结果确实如期,我们并没有看到"子线程运行结束",也就是说子线程随着jvm一起被销毁了
在这里插入图片描述

疑问

为什么spring单元测试会立即销毁jvm实例,而main函数不会,我想还是跟spring容器的消亡有关,单元测试执行完最后一行,spring容器会立即销毁,此时会销毁jvm实例,后续再研究下spring、spring bean的生命周期相关的知识点

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值