标签:
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接口;
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();
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 ; } } }
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形式,一种是不定长参数形式;
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);
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的具体实现类。
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();
public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime ; } private Runtime() {} }很明显的单例模式。
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组装成一个字符串的方法。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/woliuyunyicai/article/details/48092457