Java线程执行顺序小结及线程池终止判定
2015-10-01 11:08
465 查看
以下有4种测试情况,分别为test1~4.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.Test; public class MyTest { @Test public void test1() { // test1:当线程池中所有的线程执行完毕后,才退出主线程. ExecutorService pool = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int temp = i; pool.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(temp + " finished"); } }); } pool.shutdown();// 停止加入新的线程 while (!pool.isTerminated()) { // 如果所有线程执行完成,那么挑出该循环. } System.out.println("main thread is done"); } @Test public void test2() { // test2:这种情况比较简单,先启动新线程,然后延迟2s,主线程退出. new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("new Thread"); } }).start(); delay(2000); } @Test public void test3() { // test3:这种情况就像麻烦了,如果你的程序子线程中操作时间太长,生命周期比主线程还长, // 那么主线程结束了,子线程自然也结束了.得不到子线程中想要的结果. // 测试结果:等待2s后,输出delay is over,并不会输出new Thread.因为主线程已经结束了. // 如果想保持子线程运行,则需要加入守护线程,或者阻塞主线程,等待子线程完成. new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub delay(3000); System.out.println("new Thread"); } }).start(); delay(2000);// 延迟函数 } @Test public void test4() { // test4:先来说一下输出结果:1.先输出delay is over;2.再输出new Thread. //执行到delay时候,由于主线程被阻塞,所以只能等待delay执行完后才轮到new Thread delay(2000);// 延迟函数 new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("new Thread"); } }).start(); } private void delay(long ms) { // TODO Auto-generated method stub try { Thread.sleep(ms); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("delay is over"); } }
总结:
1.使用ThreadPool时,先shutDown(不再接受新的线程进入线程池),再通过死循环判断isTerminated(阻塞主线程) 即可判定所有线程是否执行完毕.
2.如果子线程的生命周期比主线程长,应该给子线程加入守护线程,或者阻塞主线程,等待子线程完成(这和Android中的ANR类似..呵呵)
3.切记,不要以为线程在任何地方都是new,start之后就开启的.就如同上述代码的test4部分.所以开启线程时,不要放在不对的位置.
相关文章推荐