Java進程的建立,Java進程建立

來源:互聯網
上載者:User

Java進程的建立,Java進程建立
     Java線程建立有兩種形式,一種是繼承Thread,一種是實現Runnable介面。

    private class NewThread extends Thread {        @Override        public void run(){       // do Something       }    }    private class NewRunnable implements Runnable {        @Override        public void run(){       // do Something       }    }
     代碼中使用:
   new NewThread().start();   new Thread( new NewRunnable()).start();
     其實兩者本質上是相同的,Thread、Runnable源碼如下:
   class Thread implements Runnable    public interface Runnable {   /**    * When an object implementing interface <code>Runnable</code> is used    * to create a thread, starting the thread causes the object's    * <code>run </code> method to be called in that separately executing    * thread.    * <p>    * The general contract of the method <code>run</code> is that it may    * take any action whatsoever.    *    * @see     java.lang.Thread#run()    */   public abstract void run();
可以看到Thread其實本質上實現了Runnable介面;
而Java中進程該如何建立呢,有兩種實現方法:一種是使用ProcessBuilder.start來建立;一種是使用Runntime.exec實現;
一、使用ProcessBuilder.start建立1、使用:
       ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "ipconfig/all");       Process process = null;        try {              process = pb.start();       } catch (IOException e) {              e.printStackTrace();       }              System.out.println(process.isAlive());       Scanner scanner = new Scanner (process.getInputStream());               while (scanner.hasNextLine()) {              System.out.println(scanner.nextLine());       }       scanner.close();

2、先來看進程Process的主體源碼:
public abstract class Process {           abstract public OutputStream getOutputStream();   //擷取進程的輸出資料流       abstract public InputStream getInputStream();    //擷取進程的輸入資料流     abstract public InputStream getErrorStream();   //擷取進程的錯誤流     abstract public int waitFor() throws InterruptedException;   //讓進程等待     abstract public int exitValue();   //擷取進程的退出標誌     abstract public void destroy();   //摧毀進程    public Process destroyForcibly() {        destroy();        return this ;    }    public boolean isAlive() {        try {            exitValue();            return false ;        } catch(IllegalThreadStateException e) {            return true ;        }    }}

3、ProcessBuilder的建構函式:
public final class ProcessBuilder{           private List<String> command;    private File directory ;    private Map<String,String> environment;    private boolean redirectErrorStream ;    private Redirect[] redirects ;    public ProcessBuilder( List<String > command) {        if (command == null)            throw new NullPointerException();        this.command = command;    }    public ProcessBuilder( String... command) {        this.command = new ArrayList <>(command.length );        for (String arg : command)            this.command .add(arg);    }}
     支援兩種建構函式,一種是List形式,一種是不定長參數形式;
4、ProcessBuilder是通過start方法來啟動Process:
public Process start() throws IOException {    // Must convert to array first -- a malicious user-supplied    // list might try to circumvent the security check.    String[] cmdarray = command.toArray(new String[command .size()]);    cmdarray = cmdarray.clone();    for (String arg : cmdarray)        if (arg == null )            throw new NullPointerException();    // Throws IndexOutOfBoundsException if command is empty    String prog = cmdarray[0];    SecurityManager security = System.getSecurityManager();    if (security != null)        security.checkExec(prog);    String dir = directory == null ? null : directory.toString();    for ( int i = 1; i < cmdarray.length; i++) {        if (cmdarray[i].indexOf('\u0000' ) >= 0) {            throw new IOException( "invalid null character in command" );        }    }    try {        return ProcessImpl.start(cmdarray,                                 environment,                                 dir,                                 redirects,                                 redirectErrorStream);    } catch (IOException | IllegalArgumentException e) {        ......    }}
     前面是對commands的一系列處理,最終通過
     ProcessImpl.start(cmdarray,environment,dir,redirects,redirectErrorStream);
來啟動進程。
5、來看看ProcessImpl(和Android中Context,ContextImpl略像)
final class ProcessImpl extends Process {               static Process start(String cmdarray[],             java.util.Map<String,String> environment,             String dir, ProcessBuilder.Redirect[] redirects,             boolean redirectErrorStream)throws IOException{               String envblock = ProcessEnvironment.toEnvironmentBlock(environment);               try {                      .......                             return new ProcessImpl(cmdarray, envblock, dir, stdHandles, redirectErrorStream);               } finally {                      .......               }        }}
可以看到最終返回的Process的實際類型是ProcessImpl對象;ProcessImpl是抽象類別Process的具體實作類別。
二、使用Runtime.exec來建立1、使用
    String cmd = "cmd "+ "/c " +"ipconfig/all" ;    Process process = Runtime.getRuntime().exec(cmd);    Scanner scanner = new Scanner (process.getInputStream());        while(scanner.hasNextLine()){        System.out.println(scanner.nextLine());    }    scanner.close();

2、Runtime類:
public class Runtime {    private static Runtime currentRuntime = new Runtime();    public static Runtime getRuntime() {        return currentRuntime ;    }    private Runtime() {}}
很明顯的單例模式。
3、Runtime#exec:
    public Process exec(String command) throws IOException {        return exec(command, null , null );    }           public Process exec(String command, String[] envp, File dir)        throws IOException {        if (command.length() == 0)            throw new IllegalArgumentException( "Empty command");        StringTokenizer st = new StringTokenizer (command);        String[] cmdarray = new String[st.countTokens()];        for (int i = 0; st.hasMoreTokens(); i++)            cmdarray[i] = st.nextToken();        return exec(cmdarray, envp, dir);    }    public Process exec(String[] cmdarray, String[] envp, File dir)        throws IOException {        return new ProcessBuilder (cmdarray)            . environment(envp)            .directory(dir)            .start();    }
    可以看到最終依然是調用ProcessBuilder.start來建立的,兩者原理實質相同;只是由於建構函式的不同,Runtime.exec方法只支援將所有commands組裝成一個字串的方法。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.