1. 程式人生 > >Java 單元測試中的多執行緒無故退出

Java 單元測試中的多執行緒無故退出

原文:https://my.oschina.net/heweipo/blog/497176

問題發現

最近在複習多執行緒相關知識,結果一動手就出現了問題,問題是這樣的,在單元測試中使用多執行緒測試,發現只要子執行緒在睡眠一段時間,程式就退出了,毫無徵兆!!!!

看看我的程式碼(請不要拘泥這段程式碼帶來的併發問題):

 public classThreadTest{
 
    classMyThreadimplementsRunnable{
         
        private int count = 0 ;
         
        publicvoidrun(){
            try
{                 Thread.sleep(1000); // 子執行緒休眠一秒,程式都退出             }catch(InterruptedExcetption e ){                 e.printStackTrace();             }             while(count < 15){                 count ++;                 System.out.println(count);             }         }     }         @Test     public
voidthreadtest()
{                   MyThread m1 = new MyThread();                   Thread t1 = new Thread(m1);         Thread t2 = new Thread(m1);         Thread t3 = new Thread(m1);                   t1.start(); // 子執行緒         t2.start(); // 子執行緒         t3.start(); // 子執行緒                  System.out.println(Thread.currentThread().getName()); // main 執行緒
    }

問題分析

最後查資料才發現:

原來這是單元測試的bug,如果把同樣的程式放在main中執行是不會出現這個問題的!

具體JUnit原始碼我不知道,不過事實就是這樣:你在單元測試中打印出當前執行緒的名稱確實是main,

然後如果在單元測試中開啟了執行緒,這個執行緒如果一直處於執行狀態的話,那麼就算單元測試執行完成,

子執行緒也不會退出;

但是,如果子執行緒處於阻塞、消亡狀態,那麼單元測試會立刻停止所有的子執行緒,同時退出程式!

問題解決

1)使子執行緒不處於阻塞狀態,那麼就算單元測試執行完成,子執行緒也不會退出;

2)可以強制要求所有子執行緒執行完成之後,在執行主執行緒,如下程式碼:

        t1.start(); // 子執行緒
        t2.start(); // 子執行緒
        t3.start(); // 子執行緒
        
        t3.join(); // 保證所有子執行緒執行完成之後,才執行下面的程式碼
        
        System.out.println(Thread.currentThread().getName()); // main 執行緒

3)不適用單元測試測試多執行緒,使用main進行測試

--------------------------------------

下面描述一下我遇到的問題:因為要測試億萬級別資料庫的刪除和抗壓能力,所以要造資料,在一個測試方法裡面起了多了執行緒,但是發現執行緒其實是開始執行了的,資料也有插入,就是執行屁大一會兒就之行結束了,各種找不到原因之後才發現是這個原因。

在測試程式碼裡面,主執行緒死了之後,其它執行緒也會跟著死掉。