Java进程的创建
来源:互联网 发布:如何做好商务工作 知乎 编辑:程序博客网 时间:2024/05/20 00:35
Java线程创建有两种形式,一种是继承Thread,一种是实现Runnable接口。
2、先来看进程Process的主体源码:
3、ProcessBuilder的构造函数:
2、Runtime类:
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组装成一个字符串的方法。
0 0
- Java进程的创建
- Java并发编程:线程、进程的创建
- JAVA 创建进程的两种方式
- Java创建进程
- java创建进程
- Java创建进程
- java 创建一个进程
- Java并发编程:(1)进程和线程的由来、进程的创建、线程的创建
- 创建进程的例子
- 进程的创建
- 进程的创建
- 进程的创建
- 进程的创建
- Windows进程的创建
- Windows的进程创建
- 进程的创建过程
- 进程的创建
- Windows的进程创建
- HDU 5422:Rikka with Graph
- “我爱智能”原创性博客索引
- LeetCode Linked List Cycle
- 安卓 requestFeature() must be called before adding content 错误
- 惠普实训一周心得
- Java进程的创建
- java mysql 编码总结
- TextNut文件保存路径
- 朱凯的
- 统计 MySQL 数据库中每个表数据与索引占用的空间大小
- Linux入手
- 不适用工具类解析Json
- C模板实现STL容器中的vector
- 二叉树的建立