主线程都结束了,为何进程还在执行?
2019-09-16 15:25
190 查看
本人在做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个步骤
- 优秀软件开发人员的态度
- 如何正确执行功能API测试
点击查看公众号地图
相关文章推荐
- 那些年犯过的错:主线程都结束了,为何进程还在执行?
- Linux_多核系统下绑定进程或线程到指定CPU_核执行
- C# 执行cmd命令,以进程的形式执行应用程序,在新的线程中执行耗时的功能逻辑
- 进程、线程、并发执行的概念
- Linux_多核系统下绑定进程或线程到指定CPU_核执行
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
- 线程执行N次后,进程执行M次,如此循环S次
- 跨进程通讯Binder的onTransact方法一定在binder线程池的binder线程中执行吗?
- spring 装配bean后执行后台进程任务处理线程的处理方式
- [Java 09 多线程] 线程是指一个进程在执行过程中可以产生更小的程序单元
- 多核CPU并不能让进程的多条线程同时执行
- 利用远程线程将代码注入到目标进程中执行
- python编程(你的电脑能够执行多少线程和进程)
- 进程、线程、并发执行的概念
- [Java 09 多线程] 线程是指一个进程在执行过程中可以产生更小的程序单元
- JAVA线程--1(程序,进程,线程,线程类,线程的调度策略及其执行过程)
- jstack_查看当前进程及所属线程执行情况
- 远程线程模板(将执行代码写入目标进程)
- Linux_多核系统下绑定进程或线程到指定CPU_核执行和调优
- 利用远程线程将代码注入到目标进程中执行