主線程都結束了,為何進程還在執行
- 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(); } } }
技術類文章精選
- java一行代碼打印心形
- Linux性能監控軟件netdata中文漢化版
- 接口測試代碼覆蓋率(jacoco)方案分享
- 性能測試框架
- 如何在Linux命令行界面愉快進行性能測試
- 圖解HTTP腦圖
- 如何測試概率型業務接口
- httpclient處理多用戶同時在線
- 將swagger文檔自動變成測試代碼
- 五行代碼構建靜態博客
- httpclient如何處理302重定向
- 基於java的直線型接口測試框架初探
- Tcloud 雲測平台–集大成者
非技術文章精選
- 為什麼選擇軟件測試作為職業道路?
- 成為傑出Java開發人員的10個步驟
- 寫給所有人的編程思維
- 自動化測試的障礙
- 自動化測試的問題所在
- 測試之《代碼不朽》腦圖
- 成為優秀自動化測試工程師的7個步驟