• [Java][Android][Process] 分享 Process 运行命令行封装类型


    我在以前的文章中提到,使用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线程的时候都不会发生此问题。与大家分享特此。

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    实用Javascript调试技巧
    fetch的常见问题及其解决办法
    为什么重复的GET请求变慢了?
    JavaScript深入浅出第4课:V8引擎是如何工作的?
    一步一步搭建前端监控系统:如何定位前端线上问题?
    如何使用 Set 来提高JS代码的性能
    详解Vue的slot新用法
    详解Vue响应式原理
    BeautyWe.js 一套专注于微信小程序的开发范式
    await Task.Yield()和await Task.CompletedTask有什么不同
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4750175.html
Copyright © 2020-2023  润新知