主線程都結束了,為何進程還在執行

  • 2019 年 10 月 4 日
  • 筆記

本人在做APP性能測試的過程中,曾經遇到過一個比較尷尬的問題,主線程已經結束,但是程序依然在執行,但沒有找到在執行什麼,一時非常苦惱。先分享一下自己的代碼,再說我找到的原因。

public static void main(String[] args) {          String timess = args[0];          int times = Common.getInstance().changeStringToInt(timess);          for (int i = 0; i < times; i++) {              Date start = Common.getInstance().getDate();              StartApp startApp = new StartApp();// 新建啟動app線程              Logcat logcat = new Logcat();// 新建記錄log線程              PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能監控              performanceThread.start();              startApp.start();              logcat.start();              execCmdAdb(command, "monkey" + getNow() + ".log");              startApp.stopThread();              logcat.stopLoacat();              performanceThread.stopRecord();              Date end = Common.getInstance().getDate();              Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");          }          output("結束monkey了!");      }  

就是新啟了幾個線程,我猜測應該是這些線程沒有很好的結束掉,導致後面出現很多問題。經過檢查發現在啟動APP的線程裏面。這個線程做的事情就是每分鐘啟動一次APP,並檢查一下WiFi狀態,使WiFi保持開/關,十分鐘反轉一下WiFi的狀態。主線程結束後,這些進程還在sleep()休眠狀態,所以才會沒找到執行的代碼。分享一下這個類有問題的代碼:

@Override      public void run() {          while (MKEY) {              int num = Common.getInstance().getRandomInt(4);              if (num == 1) {                  stopJuziApp();                  Common.getInstance().sleep(500);              }              Common.getInstance().sleep(60 * 1000);              keepWifiONorOFF(WIFISTATUS);              startJuziApp();          }      }  
public void run() {          while (WIFIKEY) {              for (int i = 0; i < 10; i++) {                  if (WIFIKEY) {                      break;                  }                  Common.getInstance().sleep(60 * 1000);                  keepWifiONorOFF(WIFISTATUS);              }              WIFISTATUS = !WIFISTATUS;// 反轉WiFi狀態          }      }  

就是因為這裏面的sleep()導致了之前的原因,後來我把WiFiswitch的代碼改掉了,放在startAPP裏面方法裏面了。然後在用java多線程裏面的join方法在每個線程加入到主線程,這樣就可以避免主線程結束而其他線程還在運行的尷尬了。分享改之後的代碼:

public static void main(String[] args) throws InterruptedException {          String timess = args[0];          int times = Common.getInstance().changeStringToInt(timess);          for (int i = 0; i < times; i++) {              Date start = Common.getInstance().getDate();              StartApp startApp = new StartApp();// 新建啟動app線程              Logcat logcat = new Logcat();// 新建記錄log線程              PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能監控              performanceThread.start();              startApp.start();              logcat.start();              execCmdAdb(command, "monkey" + getNow() + ".log");              startApp.stopThread();              logcat.stopLoacat();              performanceThread.stopRecord();              logcat.join();              performanceThread.join();              startApp.join();              Date end = Common.getInstance().getDate();              Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");          }          output("結束monkey了!");      }  

或者可以封裝一個方法來完成:

    public static void main(String[] args) throws InterruptedException {          String timess = args[0];          int times = Common.getInstance().changeStringToInt(timess);          for (int i = 0; i < times; i++) {              Date start = Common.getInstance().getDate();              StartApp startApp = new StartApp();// 新建啟動app線程              Logcat logcat = new Logcat();// 新建記錄log線程              PerformanceThread performanceThread = new PerformanceThread("monkey", package_name);// 性能監控              performanceThread.start();              startApp.start();              logcat.start();              execCmdAdb(command, "monkey" + getNow() + ".log");              startApp.stopThread();              logcat.stopLoacat();              performanceThread.stopRecord();              joinThread(logcat, startApp, performanceThread);              Date end = Common.getInstance().getDate();              Common.getInstance().outputTimeDiffer(start, end, "第" + i + "次");          }          output("結束monkey了!");      }        /**       * 把所有線程加入到主線程裏面       *       * @param threads       */      public static void joinThread(Thread... threads) {          for (Thread thread : threads) {              try {                  thread.join();              } catch (InterruptedException e) {                  e.printStackTrace();              }          }      }  

技術類文章精選

  1. java一行代碼打印心形
  2. Linux性能監控軟件netdata中文漢化版
  3. 接口測試代碼覆蓋率(jacoco)方案分享
  4. 性能測試框架
  5. 如何在Linux命令行界面愉快進行性能測試
  6. 圖解HTTP腦圖
  7. 如何測試概率型業務接口
  8. httpclient處理多用戶同時在線
  9. 將swagger文檔自動變成測試代碼
  10. 五行代碼構建靜態博客
  11. httpclient如何處理302重定向
  12. 基於java的直線型接口測試框架初探
  13. Tcloud 雲測平台–集大成者

非技術文章精選

  1. 為什麼選擇軟件測試作為職業道路?
  2. 成為傑出Java開發人員的10個步驟
  3. 寫給所有人的編程思維
  4. 自動化測試的障礙
  5. 自動化測試的問題所在
  6. 測試之《代碼不朽》腦圖
  7. 成為優秀自動化測試工程師的7個步驟