JUnit不支持多线程

今天遇到了一个坑,也就是Junit写测试类的时候无法完成多线程的编写,之后简单的看了看源码,发现,Junit的确是不支持的

package superbook.utilTest;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ThreadLocalRandom;

import org.junit.Test;

import superbook.util.DBUtil;

public class DBUtilTest {
	DBUtil dbUtil = new DBUtil();

	@Test
	public void getConnection() throws SQLException, InterruptedException {
		System.out.println(dbUtil.getConnection());
		Thread A = new Thread() {
			@Override
			public void run() {
				try {
					for(int i = 0; i<10; i++ ) {
						Connection a = DBUtil.getConnection();
						System.out.println(a);

						System.out.println(i+"线程A获得Connection为: " + a);
					}
				}catch (Exception e) {

				}
			}
		};
		Thread B = new Thread() {
			@Override
			public void run() {
				try {
					for(int i = 0; i<100; i++ ) {
						Connection a = dbUtil.getConnection();
						System.out.println(i+"线程B获得Connection为: " + a);
					}
				}catch (Exception e) {

				}
			}
		};
		A.start();
		B.start();
	}
}

这是他的输出

jdbc:mysql://127.0.0.1:3306/superbook?userUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
com.mysql.cj.jdbc.ConnectionImpl@37f1104d
jdbc:mysql://127.0.0.1:3306/superbook?userUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc:mysql://127.0.0.1:3306/superbook?userUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false

截取了部分源码
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部分源码

protected  List    fFailures
protected  List    fErrors

public synchronized boolean wasSuccessful() {
    return failureCount() == 0 && errorCount() == 0;
}

public synchronized int errorCount() {
    return fErrors.size();
}

public synchronized int failureCount() {
    return fFailures.size();
}

由上可以看出在TestRunner中,如果是单线程,当测试主线程执行结束后,不管子线程是否结束,都会回调TestResult的wasSuccessful方法,

然后判断结果是成功还是失败,最后调用相应的System.exit()方法。大家都知道这个方法是用来结束当前正在运行中的java虚拟机,那么线程也就都结束了

解决办法:

1 简单粗暴地让主线程休眠一段时间,然后让子线程能够运行结束。但是这个方法的弊端是,你不知道子线程的运行时间,所以需要看脸=_=

Thread.sleep();

2 使用CountDownLatch工具类,让主线程阻塞,直到子线程运行结束或者阻塞超时,这个方法要比第一个方法好点。

countDownLatch.await(5, TimeUnit.MINUTES);

你可能感兴趣的:(Thread)