junit单元测试不支持多线程测试

今天看《高并发》书,写了一个多线程的类,发现测试方法输出的结果并不对;
同样的代码,经过main方法后输出的结果却是正常的;经过研究后发现单元测试@Test并不支持多线程测试;以下为分析过程:
private static ExecutorService ex = Executors.newFixedThreadPool(5);
	
	public static class myTask implements Runnable{
		@Override
		public void run() {
			long s0 = System.currentTimeMillis();
			System.out.println(s0 + ":" + Thread.currentThread().getId());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				Logger.getLogger(getClass()).debug("线程异常");
			}
		}
	}
	
	/**
	 * @discription 这个测试类只能输出5条线程数据,原因为在@Test的junit_jar包中TestRunner方法有个特性:当测试类的主线程完成后回直接关闭jvm(System.exit),不会等待子线程运行完;所以主线程会在第一批线程处理完成后直接退出
	 * @author liu_l       
	 * @created 2017年5月12日 上午10:21:26     
	 * @throws InterruptedException
	 */
	@Test
	public void test() throws InterruptedException{
		myTask task = new myTask();
		for(int i=0; i<10; i++){
			ex.execute(task);
		}
	}

输出结果为:

time:1494558540525____ThreadId:10
time:1494558540525____ThreadId:11
time:1494558540525____ThreadId:12
time:1494558540526____ThreadId:13
time:1494558540526____ThreadId:14
这个输出明显是有问题的,讲道理在线程池这5条线程运行完过一秒会有相同的5条线程继续执行剩下来的5条线程;正常输出结果:
time:1494558751747____ThreadId:9
time:1494558751747____ThreadId:11
time:1494558751747____ThreadId:10
time:1494558751747____ThreadId:12
time:1494558751747____ThreadId:13
time:1494558752747____ThreadId:10
time:1494558752747____ThreadId:11
time:1494558752747____ThreadId:9
time:1494558752747____ThreadId:13
time:1494558752747____ThreadId:12
那么问题来了,why?这时候我想起来看下Junit4 TestRunner源码:
	public static final int SUCCESS_EXIT = 0;
	public static final int FAILURE_EXIT = 1;
	public static final int EXCEPTION_EXIT = 2;
	
	public static void main(String args[]) {
		TestRunner aTestRunner= new TestRunner();
		try {
			TestResult r= aTestRunner.start(args);
			if (!r.wasSuccessful()) 
				System.exit(FAILURE_EXIT);
			System.exit(SUCCESS_EXIT);
		} catch(Exception e) {
			System.err.println(e.getMessage());
			System.exit(EXCEPTION_EXIT);
		}
	}
再看看TestResult类:
	/**
	 * Returns whether the entire test was successful or not.
	 */
	public synchronized boolean wasSuccessful() {
		return failureCount() == 0 && errorCount() == 0;
	}
在这里我们明显可以看到:当aTestRunner调用start方法后不会去等待子线程执行完毕在关闭主线程,而是直接调用TestResult.wasSuccessful()方法,而这个方法始终返回的是false,所以主线程接下来就会执行System.exit,这个放回会结束当前运行的jvm虚拟机,所以使用junit测试多线程方法的结果异常就正常了;
(ps:想要正常输出的话可以让主线程不要结束,等待子线程全部运行结束后在结束主线程,输出结果就会正常,下面会junit测试多线程正常输出的方法:`@Test
public void test1() throws InterruptedException{
	myTask task = new myTask();
	for(int i=0; i<10; i++){
		ex.execute(task);
	}
	Thread.sleep(100000);
}`)
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值