ProcessBuilder with multi-threading
Before reading this, it's probably a good idea to practice with ProcessBuilder Uppercase and ProcessBuilder and Runtime. When you finish, you may probably ask yourself: what if I want to run several commands? In this example, we run two commands in a row. When the first command finishes its execution, the second command is called, and the result of both is sent to the standard output.
We are going to run the command
ls -al followed by the command
tr '[eiou]' a. Thus, we need two child processes, one for each command. The output of the first child process is used as the input of the second child process.
ProcessBuilder again, and the method
waitFor() of class
Process. Remember to close the output stream before starting to read into the second process:
bw.close(); // Synchronization int finish = process2.waitFor();
The result of running this program is:
$ java TwoCommands 0 tatal 28 drwxrwxr-x 2 adman adman 4096 fab 28 19:50 . drwxr-xr-x 7 adman adman 4096 fab 28 19:59 .. -rw------- 1 adman adman 673 fab 28 19:50 PassThraad.java -rw------- 1 adman adman 1040 act 15 20:35 TwaCammands2.java -rw-rw-r-- 1 adman adman 1954 fab 28 19:46 TwaCammands.class -rw------- 1 adman adman 1430 fab 28 19:24 TwaCammands.java
which is the equivalent of typing:
$ ls -al | tr '[eiou]' a
in the terminal.
Streams can also be managed by using Java class
Thread. You can find wonderful examples of it in this JavaWorld comprehensive article.
TwoCommands2.java is an adapted version of those examples, where we eliminate the lines where the stream of
process1 is sent manually to
process2, and instead they are wrapped into a thread:
PassThread wrapper = new PassThread( is1, os ); new Thread(wrapper).start(); // Synchronization int finish = process2.waitFor();
For this, another class,
PassThread, is implemented.
To compile, type:
$ javac pbMultithread/TwoCommands2.java
and to run:
$ java pbMultithread.TwoCommands2