我有一个Java应用程序,它使用一些参数启动另一个应用程序。 Java应该能够同时继续并在用户输入后终止其他应用程序。
阅读本文后,我发现我应该使用Thread.Interupt()
因为Thread.Stop()
已被弃用。
在你的线程上它会抛出一个InterruptedExection。所以我拥有的是:
public class ProcessExecutor extends Object implements Runnable {
private volatile int id;
private String message;
private Process proc = null;
public ProcessExecutor(int id, String message) {
this.id = id;
this.message = message;
}
public int GetId() {
return id;
}
public void run() {
try {
String[] cmd = new String[4];
cmd[0] = "path to some app";
cmd[1] = id;
cmd[2] = message;
Runtime rt = Runtime.getRuntime();
proc = rt.exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line=null;
while ((line=input.readLine()) != null) {
System.out.println("ProcessExecutor: " + line);
}
int exitVal = proc.waitFor();
System.out.println("ProcessExecutor: Exited with error code " + exitVal);
} catch(InterruptedException ex) {
System.out.println("ProcessExecutor: stopping");
if (proc != null) {
proc.destroy();
proc = null;
}
} catch(Exception e) {
System.out.println("ProcessExecutor: exception: " + e.toString());
e.printStackTrace();
}
}
}
由以下人员处理:
private List<Thread> activeProccesses = new ArrayList<Thread>();
public void StartProcess(int id, String message) {
System.out.println("StartProcess: id=" + id + ", message='" + message + "'");
StopAllProcesses();
ProcessExecutor proc = new ProcessExecutor(id, message);
Thread procThread = new Thread(proc);
activeProccesses.add(procThread);
procThread.start();
}
public void StopAllProcesses() {
System.out.println("Stopping all processes");
Iterator<Thread> it = activeProccesses.iterator();
while (it.hasNext()) {
Thread procThread = it.next();
if (procThread.isAlive()) {
procThread.interrupt();
}
it.remove();
}
System.out.println("Stopping all processes: done");
}
procThread.interrupt()
如何执行但catch(InterruptedException ex)
永远不会命中。
为什么会这样,我该如何解决?
编辑:结论
原帖由input.readLine()
阻止,以阻止我必须直接停止Process
,然后取消阻止input.readLine()
。
public class ProcessExecutor extends Thread {
private volatile int id;
private String message;
private volatile Process proc = null;
public ProcessExecutor(int id, String message) {
this.id = id;
this.message = message;
}
public int GetId() {
return id;
}
public void StopProc() {
if (proc != null) {
proc.destroy();
}
}
public void run() {
try {
String[] cmd = new String[4];
cmd[0] = "path to some app";
cmd[1] = id;
cmd[2] = message;
Runtime rt = Runtime.getRuntime();
proc = rt.exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line=null;
while ((line=input.readLine()) != null) {
System.out.println("ProcessExecutor: " + line);
}
int exitVal = proc.waitFor();
proc = null;
System.out.println("ProcessExecutor: Exited with error code " + exitVal);
} catch(Exception e) {
System.out.println("ProcessExecutor: exception: " + e.toString());
StopProc();
}
}
}
private List<ProcessExecutor> activeProccesses = new ArrayList<ProcessExecutor>();
public void StartProcess(int id, String message) {
System.out.println("StartProcess: id=" + id + ", message='" + message + "'");
StopAllProcesses();
ProcessExecutor proc = new ProcessExecutor(id, message);
activeProccesses.add(proc);
proc.start();
}
public void StopAllProcesses() {
System.out.println("Stopping all processes");
Iterator<ProcessExecutor> it = activeProccesses.iterator();
while (it.hasNext()) {
ProcessExecutor proc = it.next();
proc.StopProc();
it.remove();
}
System.out.println("Stopping all processes: done");
}
答案 0 :(得分:0)
您必须在ProcessExecutor中明确检查中断的条件;不会自动抛出InterruptedException。像这样:
public class ProcessExecutor extends Object implements Runnable {
public void run() {
try {
//other code....
while ((line=input.readLine()) != null) {
System.out.println("ProcessExecutor: " + line);
if (Thread.interrupted()) {
// We've been interrupted!
throw new InterruptedException("....");
}
}
} catch(InterruptedException ex) {
System.out.println("ProcessExecutor: stopping");
}
有关详细信息,请参阅http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html。
答案 1 :(得分:0)
中断线程只有在处于特定状态时才有效,通常是在不主动处理数据时完成的wait()
调用期间完成的。
如果您希望线程在readLine()
次调用之间死亡,您可以在while检查中检查interrupted()
,而不是使用try-catch。
编辑:解决问题的最佳方法是
while (true)
{
if (input.ready())
{
line = input.readLine();
System.out.println("ProcessExecutor: " + line);
} else {
try { Thread.sleep(100); } // time to wait in ms
catch (InterruptedException ie) { break; }
}
}
由于ready()
实际上会检查单个字符,因此您应该使用连续的read()
而不是readLine()
,但如果您在流上写入一行一行应该没有区别办法。等待的时间显然是随意的。
答案 2 :(得分:0)
我建议更优雅的方式来阻止线程。在run方法中,您有以下代码
while ((line=input.readLine()) != null) {
System.out.println("ProcessExecutor: " + line);
}
在ProcessExecutor
中,添加一个布尔字段,并附带其getter和setter。
private Boolean stop = false;
并在条件状态下检查相同的标志。
while (((line=input.readLine()) != null) && !stop) {
System.out.println("ProcessExecutor: " + line);
}
在StopAllProcesses()
方法中,在stop=true
个实例上设置ProcessExecutor
。这将导致run()
方法返回并正常停止线程。
答案 3 :(得分:0)
正如我在评论中所说。我认为中断线程阻止读取一行的唯一方法是杀死线程读取的进程。正如阻止线程阻塞读取套接字的唯一解决方案是关闭套接字。
在您的线程中添加一个破坏该过程的方法。