我在以前的文章中提到,使用Java不会有一个问题,创建运行命令来创建太多进程后创建进程行语句。
[Android] ProcessBuilder与Runtime.getRuntime().exec分别创建进程的差别
进行多次測试后发现是由于没有正常退出进程,以及全然读取掉流数据。和关闭流导致的问题。
在多次优化后,建立例如以下封装类:
ProcessModel.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; /** * Create By Qiujuer * 2014-07-26 * <p/> * 运行命令行语句静态方法封装 */ public class ProcessModel { //换行符 private static final String BREAK_LINE; //运行退出命令 private static final byte[] COMMAND_EXIT; //错误缓冲 private static byte[] BUFFER; /** * 静态变量初始化 */ static { BREAK_LINE = " "; COMMAND_EXIT = " exit ".getBytes(); BUFFER = new byte[32]; } /** * 运行命令 * * @param params 命令參数 * <pre> eg: "/system/bin/ping", "-c", "4", "-s", "100","www.qiujuer.net"</pre> * @return 运行结果 */ public static String execute(String... params) { Process process = null; StringBuilder sbReader = null; BufferedReader bReader = null; InputStreamReader isReader = null; InputStream in = null; InputStream err = null; OutputStream out = null; try { process = new ProcessBuilder() .command(params) .start(); out = process.getOutputStream(); in = process.getInputStream(); err = process.getErrorStream(); out.write(COMMAND_EXIT); out.flush(); process.waitFor(); isReader = new InputStreamReader(in); bReader = new BufferedReader(isReader); String s; if ((s = bReader.readLine()) != null) { sbReader = new StringBuilder(); sbReader.append(s); sbReader.append(BREAK_LINE); while ((s = bReader.readLine()) != null) { sbReader.append(s); sbReader.append(BREAK_LINE); } } while ((err.read(BUFFER)) > 0) { } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { closeAllStream(out, err, in, isReader, bReader); if (process != null) { processDestroy(process); process = null; } } if (sbReader == null) return null; else return sbReader.toString(); } /** * 关闭全部流 * * @param out 输出流 * @param err 错误流 * @param in 输入流 * @param isReader 输入流封装 * @param bReader 输入流封装 */ private static void closeAllStream(OutputStream out, InputStream err, InputStream in, InputStreamReader isReader, BufferedReader bReader) { if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } if (err != null) try { err.close(); } catch (IOException e) { e.printStackTrace(); } if (in != null) try { in.close(); } catch (IOException e) { e.printStackTrace(); } if (isReader != null) try { isReader.close(); } catch (IOException e) { e.printStackTrace(); } if (bReader != null) try { bReader.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 通过Android底层实现进程关闭 * * @param process 进程 */ private static void killProcess(Process process) { int pid = getProcessId(process); if (pid != 0) { try { //android kill process android.os.Process.killProcess(pid); } catch (Exception e) { try { process.destroy(); } catch (Exception ex) { } } } } /** * 获取进程的ID * * @param process 进程 * @return */ private static int getProcessId(Process process) { String str = process.toString(); try { int i = str.indexOf("=") + 1; int j = str.indexOf("]"); str = str.substring(i, j); return Integer.parseInt(str); } catch (Exception e) { return 0; } } /** * 销毁进程 * * @param process 进程 */ private static void processDestroy(Process process) { if (process != null) { try { //推断是否正常退出 if (process.exitValue() != 0) { killProcess(process); } } catch (IllegalThreadStateException e) { killProcess(process); } } } }
在进行批量压力測试到达125643线程的时候都不会发生此问题。与大家分享特此。
版权声明:本文博客原创文章,博客,未经同意,不得转载。