今天用junit测试代码突然发现,多线程无法执行完结果就结束程序了,后来在网上找了找原因:
场景比较特殊,一 使用到了springboot的@test,二 使用了线程池
1原因:
junit在运行时,在主线程结束后就关闭了进程,不会等待各个线程运行结束,junit源码
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);
}
}
2解决方法
①要是要求不高,可以通过thread.sleep(),让主线程暂时休眠,其他线程运行完在结束
②比较严谨的做法,可以用 CountDownLatch ,具体使用在代码里有注释
//初始化一个发令枪对象,计数为3
private static CountDownLatch latch = new CountDownLatch(3);
@Test
public void test118(){
identifyLawBatch.handlerLaw(latch);
try {
// 当计数为0时结束阻塞
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
@Repository
public class IdentifyLawBatch {
public static void main(String[] args) {
IdentifyLawBatch ib = new IdentifyLawBatch();
}
static ExecutorService fixedThreadPool = null;
//初始化固定线程数的线程池
static {
fixedThreadPool = Executors.newFixedThreadPool(3);
}
public void handlerLaw(CountDownLatch latch){
fixedThreadPool.execute(new IdentifyLawRun(1,11,latch));
fixedThreadPool.execute(new IdentifyLawRun(11,110,latch));
fixedThreadPool.execute(new IdentifyLawRun(21,210,latch));
}
}
//识别没有版本的law任务
public class IdentifyLawRun implements Runnable {
CountDownLatch latch = null;
//传入查询的数据区间
Integer beginNum = 0;
Integer endNum = 0;
public IdentifyLawRun(int beginNum,int endNum,CountDownLatch latch){
this.beginNum = beginNum;
this.endNum = endNum;
this.latch = latch;
}
@Override
public void run() {
System.out.println(beginNum);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(endNum);
//每次计数减一
latch.countDown();
}
}