主线程都结束了,为何进程还在执行

  • 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个步骤