Junit 多线测试 问题

问题

在使用Junit测试时,发现在测试方法中启动新的线程,结果新开启的线程未执行,测试方法就结束了。难道Junit不支持多线程测试?

示例如下:

public class ThreadTest {
    @Test
    public void testSleep() {
        Thread t = new Thread(()-> {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }
            System.out.println("--------");
        });
        
        t.start();

        System.out.println("end...");
    }
}

第一想法就是 在junit中启动的线程都是daemon的?线程调用start() 方法后是不能修改线程的daemon状态的。 还可能一种可能就是,执行完主线程后就直接System.exit() 退出jvm。

下面我们分析下源码,看看到底是什么情况

Debug模式下运行 testSleep() 方法,如下:

通过 Junit 运行 testSleep() 方法,我们发现Junit的运行启动主类:

org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.java

执行的方法 RemoteTestRunner.main(String arg[])

RemoteTestRunner.main() 源码分析

public static void main(String  JavaDoc[] args) {
    try {
        RemoteTestRunner testRunServer= new RemoteTestRunner();
        testRunServer.init(args);
        testRunServer.run();
    } catch (Throwable  JavaDoc e) {
        e.printStackTrace(); // don't allow System.exit(0) to swallow exceptions
    } finally {
        // fix for 14434
        System.exit(0);
    }
}

从代码中我们发现,当执行完testSleep()方法的主线程时,就会调用 finally里面的 System.exit(0) 方法,让JVM强制退出。这是在testSleep()方法中启动的新线程也就强制停止了,而不会打印线程中输出的信息。

解决办法

最简单的解决办法如下:

@Test
public void testSleep() throws InterruptedException {
    Thread t = new Thread(()-> {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
        }
        System.out.println("--------");
    });
        
    t.start();
    
    System.out.println("end...");
    
    t.join();
//  TimeUnit.SECONDS.sleep(1000);
    }

也可以使用 FutrueTask、CountDownLatch等。


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码神联盟

珍藏 | Java 岗位 100道 面试题及答案详解

9425
来自专栏Java技术分享

第三章:Shiro的配置——深入浅出学Shiro细粒度权限开发框架

Shiro配置基础知识 Shiro 被设计成能够在任何环境下工作,从最简单的命令行应用程序到最大的的企业群集应用。由于环境的多样性,使得许多配置机制适用于它的配...

2387
来自专栏封碎

Java多线程参考手册 博客分类: 经典文章转载

http://blog.csdn.net/ring0hx/article/details/6858582

742
来自专栏Golang语言社区

GO语言并发编程之互斥锁、读写锁详解

在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都...

3917
来自专栏Golang语言社区

GO语言并发编程之互斥锁、读写锁详解

在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都...

5064
来自专栏游戏杂谈

Node.js文件编码格式的转换

项目很多 lua 文件不是 utf-8格式,使用 EditPlus 查看的时候,显示为ASCII。还有的是带BOM的,带BOM倒好处理,之前写过,有一定规律。

2064
来自专栏Dawnzhang的开发者手册

Spring中的@Transactional(rollbackFor = Exception.class)属性详解

今天我在写代码的时候,看到了。一个注解@Transactional(rollbackFor = Exception.class),今天就和大家分享一下,这个注解...

2001
来自专栏Golang语言社区

GO语言并发编程之互斥锁、读写锁详解

在本节,我们对Go语言所提供的与锁有关的API进行说明。这包括了互斥锁和读写锁。我们在第6章描述过互斥锁,但却没有提到过读写锁。这两种锁对于传统的并发程序来说都...

2865
来自专栏源哥的专栏

多媒体处理类

import java.io.*; import java.util.*; import javax.servlet.http.*;

841
来自专栏小灰灰

Java并发学习之CountDownLatch实现原理及使用姿势

CountDownLatch实现原理及使用姿势 在并发编程的场景中,最常见的一个case是某个任务的执行,需要等到多个线程都执行完毕之后才可以进行,Count...

6.7K10

扫码关注云+社区

领取腾讯云代金券