标签:def new t shm 面试官 测试 array ret link interrupt
老铁们好,这里是java研究所。做java的,junit应该非常熟悉吧,天天和这哥们打交道,没想到这哥们却隐藏了一个神坑,我们一起来看下。
运行下面的main方法,会输出什么?
public class JunitTest {
public static void main(String[] args) {
System.out.println("main thread");
new Thread() {
@Override
public void run() {
System.out.println("子线程 start");
try {
//休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程 end");
}
}.start();
}
}
很明显会输出
main thread
子线程 start
子线程 end
ok,结果确实没问题。
咱们来调整一下代码,如下,将main方法中的代码用junit来运行,然后运行test1方法,大家觉得会输出什么???结果会和main方法的输出一样么??
import org.junit.Test;
public class JunitTest {
@Test
public void test1() {
System.out.println("main thread");
new Thread() {
@Override
public void run() {
System.out.println("子线程 start");
try {
//休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程 end");
}
}.start();
}
}
咱们来运行一下,纳尼,这什么情况,结果为什么比main中的少了一行????
我以为idea出问题了,然后又运行了几次,结果还是一样,估计少的结果被 junit 生吞了。
上面代码的特点:主线程中开启了子线程,如果代码是在main方法中执行,程序会等到所有线程都执行完毕才会结束;而junit会在主线程执行完毕之后,就会将程序结束。
咱们知道可以通过下面代码结束程序
java.lang.System.exit(int status) // status=0:正常退出 ,其他非正常退出
我估计junit会主线程执行完毕之后,会调用 System.exit 来退出程序,我们需要来验证一下想法,怎么验证呢??
只需要在exit方法中设置一个断点,然后重新执行程序
debug模式下,再次执行一下test1方法,果不其然,进到exit方法中了
方式1:主线程中休眠一段时间
可以预估一下测试案例会运行多久,比如10秒就够了,那么可以在方法最后一行使用sleep让线程休眠一段时间。
@Test
public void test1() throws InterruptedException {
System.out.println("main thread");
new Thread() {
@Override
public void run() {
System.out.println("子线程 start");
try {
//休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程 end");
}
}.start();
//让主线程休眠10秒
Thread.sleep(10000);
}
这种方式的优点是写起来简单,加一行代码就搞定了。
方式2:join的方式
@Test
public void test1() throws InterruptedException {
System.out.println("main thread");
Thread thread1 = new Thread() {
@Override
public void run() {
System.out.println("子线程 start");
try {
//休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程 end");
}
};
thread1.start();
//join方法会阻塞当前主线程,直到thread1线程执行完毕
thread1.join();
}
方式3:CountDownLatch
@Test
public void test1() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
System.out.println("main thread");
Thread thread1 = new Thread() {
@Override
public void run() {
try {
System.out.println("子线程 start");
try {
//休眠1秒
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程 end");
} finally {
countDownLatch.countDown();
}
}
};
thread1.start();
//countDownLatch.await方法会阻塞当前线程,直到thread1执行完毕
countDownLatch.await();
}
标签:def new t shm 面试官 测试 array ret link interrupt
原文地址:https://blog.51cto.com/15009253/2552323