我试图弄清楚线程如何在Java中运行。我想了解如何中断为运行另一个终端进程而创建的线程。我有以下主题:
终端进程需要将其输出提供给终端线程的输入流。我通过while循环设法做到了这一点。但是,如果终端进程卡住(例如,等待用户输入),这样做实际上会挂起线程。
我的问题有两个:
代码下面是运行线程的可运行实现,该线程依次运行终端进程:
public void run(){
ProcessBuilder pb=new ProcessBuilder("Enter a terminal process that hangs here");
pb.redirectErrorStream(true);
Process pr;
try {
pr = pb.start();
BufferedReader in = new BufferedReader(new
InputStreamReader(pr.getInputStream()));
String line;
try {
while ((line = in.readLine()) != null && !Thread.currentThread().isInterrupted()) {
System.out.println(line);
}
pr.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("ok!");
in.close();
//System.exit(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我期待!Thread.currentThread()。isInterrupted()来停止循环并提供中断。但是,当我通过以下代码调用中断时,它不会中断:
JButton btnKillThreads = new JButton("Kill Threads");
btnKillThreads.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for (Thread thread : threads){
thread.interrupt();
}
}
});
以下是为完整性创建线程的代码:
JButton btnStartConversion = new JButton("Start Thread");
btnStartConversion.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Runnable rt = new Thread1();
Thread t = new Thread(rt);
t.start();
threads.add(t);
}
});
答案 0 :(得分:2)
我认为你有个好的开始。唯一的问题是Thread.interrupt()
不会停止这个过程。如果线程被in.readLine()
阻止,它将不会退出,直到该进程产生输出并且线程有机会检查isInterrupted()
。
如果您想停止此过程,除了致电Thread.interrupt()
外,您还需要致电Process.destroy()
:
class MyRunnable implements Runnable {
private Process pr;
public void run() {
// ...
pr = pb.start();
}
public shutdown() {
pr.destroy();
interrupt();
}
}
您需要注册MyRunnable
并在其上调用shutdown()
,而不是在列表中注册该帖子。
至于System.exit()
上线程的行为,所有线程都将被销毁。但是,使用System.exit()
被认为是错误的形式,因为它终止应用程序而不给予线程正常关闭的机会。一个合理的工程实践是考虑正常关机并仅使用System.exit()
作为最后的手段。
答案 1 :(得分:0)
将while循环中的条件更改为:
while ((line = in.readLine()) != null && !Thread.currentThread().isInterrupted()) {
System.out.println(line);
}