如何fork一个JAVA进程

谷歌上找的一段fork出一个java进程的示例代码,分享一下

Summary

Some times it would be nice to be able to fork off a new Java process from an existing Java process.  In this wiki entry, I do just that, creating a wrapper class to the java.lang.ProcessBuilder.

The JavaProcessBuilder

This class is a convenience wrapper class and collaborates with  java.lang.ProcessBuilder to create properly constructed Java processes.

package examples.forkingjavaprocesses;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author  Christopher Bartling, Pintail Consulting LLC
 * @since  Oct 4, 2008
 */
public class JavaProcessBuilder {

    private String mainClass;
    private int startingHeapSizeInMegabytes = 40;
    private int maximumHeapSizeInMegabytes = 128;
    private String workingDirectory;
    private List<String> classpathEntries = new ArrayList<String>();
    private List<String> mainClassArguments = new ArrayList<String>();
    private String javaRuntime = "java";

    public String getMainClass() {
        return mainClass;
    }

    public void setMainClass(String mainClass) {
        this.mainClass = mainClass;
    }

    public int getStartingHeapSizeInMegabytes() {
        return startingHeapSizeInMegabytes;
    }

    public void setStartingHeapSizeInMegabytes(int startingHeapSizeInMegabytes) {
        this.startingHeapSizeInMegabytes = startingHeapSizeInMegabytes;
    }

    public int getMaximumHeapSizeInMegabytes() {
        return maximumHeapSizeInMegabytes;
    }

    public void setMaximumHeapSizeInMegabytes(int maximumHeapSizeInMegabytes) {
        this.maximumHeapSizeInMegabytes = maximumHeapSizeInMegabytes;
    }

    private String getClasspath() {
        StringBuilder builder = new StringBuilder();
        int count = 0;
        final int totalSize = classpathEntries.size();
        for (String classpathEntry : classpathEntries) {
            builder.append(classpathEntry);
            count++;
            if (count < totalSize) {
                builder.append(System.getProperty("path.separator"));
            }
        }
        return builder.toString();
    }

    public void setWorkingDirectory(String workingDirectory) {
        this.workingDirectory = workingDirectory;
    }

    public void addClasspathEntry(String classpathEntry) {
        this.classpathEntries.add(classpathEntry);
    }

    public void addArgument(String argument) {
        this.mainClassArguments.add(argument);
    }

    public void setJavaRuntime(String javaRuntime) {
        this.javaRuntime = javaRuntime;
    }

    public Process startProcess() throws IOException {
        List<String> argumentsList = new ArrayList<String>();
        argumentsList.add(this.javaRuntime);
        argumentsList.add(MessageFormat.format("-Xms{0}M", String.valueOf(this.startingHeapSizeInMegabytes)));
        argumentsList.add(MessageFormat.format("-Xmx{0}M", String.valueOf(this.maximumHeapSizeInMegabytes)));
        argumentsList.add("-classpath");
        argumentsList.add(getClasspath());
        argumentsList.add(this.mainClass);
        for (String arg : mainClassArguments) {
            argumentsList.add(arg);
        }

        ProcessBuilder processBuilder = new ProcessBuilder(argumentsList.toArray(new String[argumentsList.size()]));
        processBuilder.redirectErrorStream(true);
        processBuilder.directory(new File(this.workingDirectory));
        return processBuilder.start();
    }
}

Something to fork

The HelloWorldServer is a simple socket-based server which our test code will fork off in a new process and then call it via socket-based messages.

package examples.forkingjavaprocesses;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author  Christopher Bartling, Pintail Consulting LLC
 * @since  Oct 4, 2008 5:48:59 PM
 */
public class HelloWorldServer {

    private ServerSocket server;
    private Socket client;
    private BufferedReader in;
    private PrintWriter out;
    private String line;
    private int listenerPort;


    public HelloWorldServer(int listenerPort) {
        this.listenerPort = listenerPort;
    }

    public void startListening() {
        try {
            server = new ServerSocket(this.listenerPort);
            client = server.accept();
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            out = new PrintWriter(client.getOutputStream(), true);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        while (true) {
            try {
                line = in.readLine();
                if (line.equalsIgnoreCase("hello")) {
                    System.out.println("Hello from the server!");
                    out.println("ack");
                    out.flush();
                } else if (line.equalsIgnoreCase("stop")) {
                    try {
                        out.println("ack");
                        out.flush();
                        System.out.println("Client triggered this server to shutdown.");
                        in.close();
                        out.close();
                        server.close();
                        System.exit(0);
                    } catch (IOException e) {
                        System.out.println("Could not close.");
                        System.exit(-1);
                    }
                }
            } catch (IOException e) {
                System.out.println("Read failed");
                System.exit(-1);
            }
        }
    }

    public static void main(String[] args) {
        final HelloWorldServer helloWorld = new HelloWorldServer(Integer.parseInt(args[0]));
        helloWorld.startListening();
    }
}

The test case

package examples.forkingjavaprocesses;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * @author  Christopher Bartling, Pintail Consulting LLC
 * @since  Oct 4, 2008
 */
public class JavaProcessBuilderTests {

    private static final int LISTENER_PORT = 4444;
    private static final String CLASSPATH = "./out/production/ForkingJavaProcesses";
    private static final String WORKING_DIRECTORY = ".";

    @Test 
    public void startJavaProcess() throws Exception {
        final JavaProcessBuilder javaProcessBuilder = new JavaProcessBuilder();
        if (System.getProperty("os.name").toLowerCase().equals("mac os x")) {
            javaProcessBuilder.setJavaRuntime("/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java");
        }
        javaProcessBuilder.setWorkingDirectory(WORKING_DIRECTORY);
        javaProcessBuilder.addClasspathEntry(CLASSPATH);
        javaProcessBuilder.setMainClass("examples.forkingjavaprocesses.HelloWorldServer");
        javaProcessBuilder.addArgument(String.valueOf(LISTENER_PORT));
        final Process process = javaProcessBuilder.startProcess();
        BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));

        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    Socket socket = new Socket("localhost", LISTENER_PORT);
                    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    System.out.println("CLIENT: Sending 'hello' command.");
                    out.println("hello");
                    System.out.println("CLIENT: Received '" + in.readLine() + "' from the server.");
                    Thread.sleep(2000);
                    System.out.println("CLIENT: Sending 'stop' command.");
                    out.println("stop");
                    System.out.println("CLIENT: Received '" + in.readLine() + "' from the server.");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();

        String line;
        while ((line = br.readLine()) != null) {
            System.out.println("SERVER: " + line);
        }
    }
}


你可能感兴趣的:(java,进程,并行,fork)