正在使用Java编写程序,如下所示,该类只是在操作系统级别执行命令。然而,有时我们遇到程序卡住的问题,因此命令永远不会返回任何状态,因此线程不会终止。
现在我正在尝试增强代码,添加一个额外的东西,我可以杀死特定的线程。我已经捕获了ThreadId,所以,这可行吗?
public class ExecuteCmd implements Runnable {
String ProcessId;
String cmd;
BackendSQL bsql;
Logger myLogger;
Thread myThread;
public ExecuteCmd(String cmd, BackendSQL bsql, String ProcessId, Logger myLogger) {
this.ProcessId=ProcessId;
this.cmd=cmd;
this.bsql=bsql;
this.myLogger=myLogger;
}
public void run() {
int rc = 0;
try {
long ThreadId = Thread.currentThread().getId();
bsql.MarkRunning(ProcessId, ThreadId);
myLogger.debug("[ExecuteCmd] Command is: "+cmd);
String[] cmdFull = cmd.split(";");
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmdFull);
myLogger.info("[ExecuteCmd] [Threading] "+ ThreadId + ": Executing command");
myLogger.debug("[ExecuteCmd] Command is: "+cmd);
BufferedReader inStream = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inStreamLine = null;
String inStreamLinebyLine=null;
while((inStreamLine = inStream.readLine()) != null) {
inStreamLinebyLine = inStreamLinebyLine+"\n"+inStreamLine;
}
myLogger.info("Command getInputStream: " + inStreamLinebyLine);
try {
rc = p.waitFor();
if (rc == 0) {
bsql.MarkCompleted(ProcessId);
}else{
bsql.MarkFailed(ProcessId);
}
} catch (InterruptedException intexc) {
System.out.println("Interrupted Exception on waitFor: " +
intexc.getMessage());
}
}catch (IOException IOE) {
myLogger.error("IOException[ExecuteCmd]: " + IOE.getMessage());
}catch (Exception e) {
myLogger.error("Exception[ExecuteCmd]: " + e.getMessage());
}
}
}
答案 0 :(得分:3)
您应该将ExecuteCmd的实例提交给ExecutorService。这样,您就可以取消或中断任务。
Process#waitFor()是一个可中断的操作,因此它应该可以正常工作。
ExecutorService service = Executors.newSingleThreadedExecutor();
Future<?> future = service.submit(new ExecuteCmd(...));
if (takingTooLong()) {
future.cancel(true);
}
答案 1 :(得分:1)
要解决您的基本问题(以及为什么需要中断某个过程),我怀疑您的流程已暂停,因为您没有消耗标准输出和标准错误并发。基本上,如果您不这样做,那么您生成的进程可能会挂起。这是一个非常普遍的问题。有关详细信息和修复,请参阅this answer。
另请参阅this Java Specialist newsletter有关如何干净地关闭线程(通过Thread.interrupt()),以及如何在正在关闭的线程中正确处理此问题。即使您使用Executor框架等,也需要正确处理关闭,因为它们会中断您的线程。
但是,如果你同时使用你的程序stdout / err,我不相信你会需要这个。
答案 2 :(得分:0)
我认为Thread.Interrupt是你要找的东西,你必须从另一个线程调用它。
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#interrupt%28%29