java 8
API
First, let's take a look at the Process
class from Java API Docs together.
** Class Process ** java.lang.Object java.lang.Process
The ProcessBuilder.start () and Runtime.exec methods create a native process and return an instance of a subclass of Process, which you can use to control and get information about that process. The Process class provides methods for inputting from a process, outputting to a process, waiting for process completion, checking the process termination status, and destroying (terminating) the process. For example, a native windowing process, a daemon process, a Win16 / DOS process in a Microsoft Windows environment, or a shell script.
By default, the created subprocess does not have its own terminal or console. All that standard I / O (ie standard input, standard output, standard error) processing is redirected to the parent process, but to access that information, use the methods getOutputStream (), getInputStream (), and getErrorStream (). Use the stream retrieved using. The parent process uses these streams to send input to and get output from the subprocess. Some native platforms use a limited size of buffer for standard I / O streams, so if a subprocess fails to write an input stream or read a stream output, the subprocess is blocked or deadlocked. Can be.
If desired, you can also use methods of the ProcessBuilder class to redirect the I / O of the subprocess.
Even if there is no reference to the Process object, the subprocess will not be terminated and will continue to run asynchronously.
The execution of the process represented by the Process object may not be asynchronous or parallel to the Java process that owns the Process object.
Some native platforms use a limited size of buffer for standard I / O streams, so if a subprocess fails to write an input stream or read a stream output, the subprocess will be blocked or deadlocked. It can be in a state.
The most important thing to watch out for is the possibility of a deadlock.
bad.java
Process p = Runtime.getRuntime().exec("cmd /c dir");
//Makes the current thread wait until the process ends.
//★★★ If the standard output stream has a lot of output, the process will be blocked ★★★
p.waitFor();
The ProcessBuilder.start () and Runtime.exec methods create a native process and return an instance of a subclass of Process, which you can use to control and get information about that process.
It provides a way to control the process and get information.
To avoid the above deadlock, read the standard output stream and standard error stream from the JVM.
getInputStream
and [getErrorStream
](https://docs .oracle.com/javase/jp/8/docs/api/java/lang/Process.html#getErrorStream--) method is available
demo.java
try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line = null;
while ((line = br.readLine()) != null) {
//You don't have to output
}
} catch (IOException e) {
e.printStackTrace();
}
Even if there is no reference to the Process object, the subprocess will not be terminated and will continue to run asynchronously.
Given the instructions in the API Docs, after using the Process object, the java GC should release the Process object, but no, it's still running. So it's better to call the destroy () method.
bad.java
Process p = Runtime.getRuntime().exec("cmd /c dir");
// p.destroy();★★★ Does not end ★★★
MainTest.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
//sample
public class MainTest {
public static void main(String[] args) throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec("cmd /c cd bin && java ProcessTest");
//Output stream
new StreamThread(p.getInputStream(), "OUTPUT").start();
//Error stream
new StreamThread(p.getErrorStream(), "ERROR").start();
//Get process execution result
int result = p.waitFor();
p.destroy();
//Output data
System.out.println("■ Execution result code:" + result);
}
}
//Stream thread
class StreamThread extends Thread {
private InputStream in;
private String type;
public StreamThread(InputStream in, String type) {
this.in = in;
this.type = type;
}
@Override
public void run() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(in, "MS932"))) {
String line = null;
while ((line = br.readLine()) != null) {
//Output logs etc.
System.out.println(type + ">" + line);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ProcessTest.java
public class ProcessTest {
public static void main(String[] args) {
for (int i = 1; i <= 1000; i++) {
//Standard output
System.out.println("This is standard output:" + i + "Turn.");
//Standard error
System.err.println("This is a standard error:" + i + "Turn.");
}
}
}
Recommended Posts