我已经玩了一段时间的java进程并且卡住了。我想要做的是同时运行多个系统命令并将其输出打印到控制台。
例如,ls -l ; cat someFile ; quit ; grep foo someOtherFile
应该同时运行。我在某处读过这些命令的输出应该是混合的。另外,如果字符串中的任何地方都有quit
命令,继续执行其他命令然后退出。
现在,他们正在按顺序执行。如何同时运行它们并在它到达时打印输出。
String st = "ls -l ; cat someFile ; quit ; grep foo someOtherFile";
String[] rows = st.split(";");
String[][] strArray = new String[rows.length][];
int index = 0;
for(int i = 0; i < rows.length; i++) {
rows[index] = rows[index].trim();
strArray[index] = rows[index].split(" ");
index++;
}
for(int i = 0; i < strArray.length; i++) {
if(rows[i].equalsIgnoreCase("quit")) {
System.out.println("Abort");
break;
}
if(rows[i].equals("")) {
continue;
}
ProcessBuilder pb = new ProcessBuilder(strArray[i]);
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
答案 0 :(得分:1)
只需将循环的内容放在新线程的run()函数中,循环的每次迭代都将在一个单独的线程中运行:
new Thread() {
public void run() {
// loop guts go here
}
}.start();
您可能必须将一些变量声明为终结,以便在此匿名内部类中访问它们。
答案 1 :(得分:0)
你应该查看一些关于并发性的文档,如此http://docs.oracle.com/javase/tutorial/essential/concurrency/。
这里是对您的代码的编辑,可能有效,未经过测试。
String st = "ls -l ; cat someFile ; quit ; grep foo someOtherFile";
String[] rows = st.split(";");
String[][] strArray = new String[rows.length][];
int index = 0;
for(int i = 0; i < rows.length; i++) {
rows[index] = rows[index].trim();
strArray[index] = rows[index].split(" ");
index++;
}
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i < strArray.length; i++) {
if(rows[i].equalsIgnoreCase("quit")) {
System.out.println("Abort");
break;
}
if(rows[i].equals("")) {
continue;
}
final int iForThread = i;
Thread thread = new Thread() {
public void run(){
try{
ProcessBuilder pb = new ProcessBuilder(strArray[iForThread]);
pb.redirectErrorStream(true);
Process process = pb.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ( (line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}catch(IOException e){
//Log some awesome error
//Clean up
//Do whatever
}
}
};
threads.add(thread);
}
final CyclicBarrier gate = new CyclicBarrier(threads.size() + 1); //+1 is a tip from other post
for(Thread thread : threads){
thread.start();
}
try {
gate.await();
System.out.println("all threads started");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
/* RONALDO OF ERROS
* MESSI OF HANDLERS*/
}
}
它创造了一个胎面并在现场执行。 我,如果你只是搞乱我认为这就够了。
编辑:在&#34;同一时间&#34;
添加了开始线程基于:How to start two threads at "exactly" the same time
请参阅:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html
答案 2 :(得分:0)
您可以尝试与此类似的代码:
// command list
String st = "ls -la; cat someFile";
String[] commands = st.split(";");
for (int i = 0; i < commands.length; i++) {
String currentCommand = commands[i].trim();
System.out.println("Command: " + currentCommand);
Thread thread = new Thread(() -> {
try {
ProcessBuilder command = new ProcessBuilder(currentCommand);
Process process = command.start();
InputStream is = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
});
thread.start();
}
免责声明:未在Linux机器上测试过。 Windows机器可能无法正常工作。有关Windows命令行流程执行的信息,请参阅this link。