溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java?Runtime的使用方法是什么

發(fā)布時(shí)間:2021-12-15 17:05:26 來(lái)源:億速云 閱讀:130 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Java Runtime的使用方法是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

    前言

    最近做項(xiàng)目框架,需要在框架結(jié)束的時(shí)候,關(guān)閉服務(wù)器連接,清除部分框架運(yùn)行l(wèi)ock文件,這里就想到了shutdownhook,順便學(xué)了學(xué)Runtime的使用

    1. shutdownhook

    demo示例,證明在程序正常結(jié)束的時(shí)候會(huì)調(diào)用,如果kill -9 那肯定就不會(huì)調(diào)用了

    public class ShutdownHookTest { 
        public static void main(String[] args) {
            System.out.println("==============application start================");
     
            Runtime.getRuntime().addShutdownHook(new Thread(()->{
                System.out.println("--------------hook 1----------------");
            }));
            Runtime.getRuntime().addShutdownHook(new Thread(()->{
                System.out.println("--------------hook 2----------------");
            }));
     
            System.out.println("==============application end================");
        }
    }

    正常運(yùn)行結(jié)束,結(jié)果如下

    ==============application start================
    ==============application end================
    --------------hook 1----------------
    --------------hook 2----------------

    Process finished with exit code 0

    如果暫停,點(diǎn)擊下圖左下角的正方形紅圖標(biāo),停止正在運(yùn)行的應(yīng)用

    Java?Runtime的使用方法是什么

    結(jié)果如下,shutdownhook已執(zhí)行。

    Java?Runtime的使用方法是什么

    shutdownhook可以處理程序正常結(jié)束的時(shí)候,刪除文件,關(guān)閉連接等

    2. exec執(zhí)行

    2.1 常規(guī)命令執(zhí)行

    demo示例如下,比如ls

    public class ShutdownHookTest { 
        public static void main(String[] args) throws InterruptedException, IOException {
            Process process = Runtime.getRuntime().exec("ls"); 
            try (InputStream fis = process.getInputStream();
                 InputStreamReader isr = new InputStreamReader(fis);
                 BufferedReader br = new BufferedReader(isr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
    }

    結(jié)果如下

    Java?Runtime的使用方法是什么

    而正常執(zhí)行結(jié)果

    Java?Runtime的使用方法是什么

    但是這個(gè)方法有遠(yuǎn)程執(zhí)行風(fēng)險(xiǎn),即在瀏覽器端通過(guò)這個(gè)方法執(zhí)行特定指令,比如執(zhí)行rm -rf *,結(jié)果就很……

    2.2 管道符

    但是遇見管道符之后就會(huì)失效,什么辦法解決,sh -c,但是不能直接用,否則獲取到的是TTY窗口信息

    public static void main(String[] args) throws IOException {
            Process process = Runtime.getRuntime().exec("sh -c ps aux|grep java"); 
            try (InputStream fis = process.getInputStream();
                 InputStreamReader isr = new InputStreamReader(fis);
                 BufferedReader br = new BufferedReader(isr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }

    結(jié)果????

    Java?Runtime的使用方法是什么

    sh -c的參數(shù)要分離,不然runtime會(huì)認(rèn)為是一個(gè)參數(shù)

    Java?Runtime的使用方法是什么

    2.3源碼分析

    跟蹤代碼,使用ProcessImpl來(lái)執(zhí)行指令

    public Process exec(String[] cmdarray, String[] envp, File dir)
            throws IOException {
            return new ProcessBuilder(cmdarray)
                .environment(envp)
                .directory(dir)
                .start();
        }

    ProcessBuilder

    // Only for use by ProcessBuilder.start()
        static Process start(String[] cmdarray,
                             java.util.Map<String,String> environment,
                             String dir,
                             ProcessBuilder.Redirect[] redirects,
                             boolean redirectErrorStream)
            throws IOException
        {
            assert cmdarray != null && cmdarray.length > 0;
     
            // Convert arguments to a contiguous block; it's easier to do
            // memory management in Java than in C.
            byte[][] args = new byte[cmdarray.length-1][];
            int size = args.length; // For added NUL bytes
            for (int i = 0; i < args.length; i++) {
                args[i] = cmdarray[i+1].getBytes();
                size += args[i].length;
            }
            byte[] argBlock = new byte[size];
            int i = 0;
            for (byte[] arg : args) {
                System.arraycopy(arg, 0, argBlock, i, arg.length);
                i += arg.length + 1;
                // No need to write NUL bytes explicitly
            }
     
            int[] envc = new int[1];
            byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc); 
            int[] std_fds; 
            FileInputStream  f0 = null;
            FileOutputStream f1 = null;
            FileOutputStream f2 = null;
     
            try {
                if (redirects == null) {
                    std_fds = new int[] { -1, -1, -1 };
                } else {
                    std_fds = new int[3];
     
                    if (redirects[0] == Redirect.PIPE)
                        std_fds[0] = -1;
                    else if (redirects[0] == Redirect.INHERIT)
                        std_fds[0] = 0;
                    else {
                        f0 = new FileInputStream(redirects[0].file());
                        std_fds[0] = fdAccess.get(f0.getFD());
                    }
     
                    if (redirects[1] == Redirect.PIPE)
                        std_fds[1] = -1;
                    else if (redirects[1] == Redirect.INHERIT)
                        std_fds[1] = 1;
                    else {
                        f1 = new FileOutputStream(redirects[1].file(),
                                                  redirects[1].append());
                        std_fds[1] = fdAccess.get(f1.getFD());
                    }
     
                    if (redirects[2] == Redirect.PIPE)
                        std_fds[2] = -1;
                    else if (redirects[2] == Redirect.INHERIT)
                        std_fds[2] = 2;
                    else {
                        f2 = new FileOutputStream(redirects[2].file(),
                                                  redirects[2].append());
                        std_fds[2] = fdAccess.get(f2.getFD());
                    }
                }
     
            return new UNIXProcess
                (toCString(cmdarray[0]),
                 argBlock, args.length,
                 envBlock, envc[0],
                 toCString(dir),
                     std_fds,
                 redirectErrorStream);
            } finally {
                // In theory, close() can throw IOException
                // (although it is rather unlikely to happen here)
                try { if (f0 != null) f0.close(); }
                finally {
                    try { if (f1 != null) f1.close(); }
                    finally { if (f2 != null) f2.close(); }
                }
            }
        }

    new UNIXProcess 環(huán)境

     /**
     * java.lang.Process subclass in the UNIX environment.
     *
     * @author Mario Wolczko and Ross Knippel.
     * @author Konstantin Kladko (ported to Linux and Bsd)
     * @author Martin Buchholz
     * @author Volker Simonis (ported to AIX)
     */
    final class UNIXProcess extends Process {

    3. 總結(jié)

    Runtime用處非常多,偏底層

    比如gc調(diào)用

    Java?Runtime的使用方法是什么

    加載jar文件

    Java?Runtime的使用方法是什么

    Runtime功能強(qiáng)大,但需要合理利用,很多攻擊是通過(guò)Runtime執(zhí)行的漏洞

    但是使用shutdownhook還是很方便的,用來(lái)做停止任務(wù)的后續(xù)處理。

    關(guān)于Java Runtime的使用方法是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI