Junit单元多线程测试子线程不执行

Junit单元测试子线程不执行

Junit单元测试子线程不执行

环境
- Junit:4
- jdk:1.8

1、现象描述

在测试CountDownLatch类时,使用main函数能够正常运行的功能,改用Junit测试时,Debug调试时不进入子线程执行,直接运行时,有时候能够执行子线程中的部分代码,具体程序如下:

import org.junit.Test;
import java.util.concurrent.CountDownLatch;

/**
* @ClassName: CountDownLatchTest
* @Description: CountDownLatch测试类
* @author Yue Chang 
* @date 2018年1月16日 上午11:31:26 
* @since 1.0
*/
public class CountDownLatchTest {

    @Test
    public void test() throws InterruptedException {

        CountDownLatch latch = new CountDownLatch(1);

        MyThread myThread = new MyThread(latch);
        Thread t1 = new Thread(myThread);
        t1.setName("t1");

        Thread t2 = new Thread(myThread);
        t2.setName("t2");

        t1.start();
        t2.start();
    }

    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(1);

        MyThread myThread = new MyThread(latch);
        Thread t1 = new Thread(myThread);
        t1.setName("t1");

        Thread t2 = new Thread(myThread);
        t2.setName("t2");

        t1.start();
        t2.start();
    }
}

class MyThread implements Runnable{

    private CountDownLatch latch;
    private volatile int number;

    /**
     * @param latch
     */
    public MyThread(CountDownLatch latch) {
        this.latch = latch;
    }

    public MyThread() {
    }

    public CountDownLatch getLatch() {
        return latch;
    }

    public void setLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public void run() {

        String threadName = Thread.currentThread().getName().trim();
        if ("t2".equals(threadName)) { // t2线程
            try {
                Thread.sleep(5000);
                System.out.println("线程0:" + threadName);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.setNumber(1);
            latch.countDown(); // 计数减1
        } else if ("t1".equals(threadName)) { // t1线程
            try {
                System.out.println("线程1:" + threadName);
                latch.await(); // 阻塞等待计数为0
                System.out.println("线程1:" + threadName);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("num = " + this.getNumber());
        }
    }
}

2、执行结果

执行Junit结果如下:

线程1:t1

或者是什么都没有打印

执行main结果如下:

线程1:t1
线程0:t2
线程1:t1
num = 1

执行t1时,由于countDownLatch值还不为0,于是将处于等待中,知道t2执行完,将countDownLatch的值减1,变为0时,t1才继续执行,最后打印出num。

3、分析

后面查找资料才知道Junit当主线程退出,子线程也会退出。这样一来也就可以解释为什么有时候执行部分,有时候完全没有执行这个现象了。

4、解决办法:

在Junit测试代码中,加上如下代码:

// junit主线程执行完之后,不会再去管子线程的执行情况,如果没有join(),那么大多数情况下子线程没法执行完
t1.join();

让主线程等待t1线程执行完,也就可以让子线程正常执行了

你可能感兴趣的:(java)