我正在创建一个运行某些线程的图形界面。 这些线程中的每一个都启动Java Process来管理VNC连接。 我想要的是通过将其存储在管理的线程的一些变量中来跟踪进程生命周期。最后,GUI与Thread通信以了解Process状态。
以下是我的代码片段:
public class VNCViewer extends Thread{
private static final String cmd = "some command";
private Process vnc;
private boolean active = false ;
public void run(){
try {
launchVNC();
} catch (IOException ex) {
Logger.getLogger(VNCViewer.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(VNCViewer.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void launchVNC() throws IOException, InterruptedException{
if (condition){
vnc = Runtime.getRuntime().exec(cmd);
active = true;
while(vnc.isAlive()){} //while the process is alive, the thread awaits
active = false;
}
}
public boolean isActive(){
return active;
}
}
在运行时发生的事情是线程跳过"而#34;循环(我试过在循环中插入一个system.out.println并且只在线程终止时打印),结果是变量" active"总是在"假"。
答案 0 :(得分:0)
由于active
不是volatile
,因此未在同步块中更新/访问,并且不是Atomic*
类之一,因此它是完全合法的Java VM假设没有人读取active=true
和active=false
之间的字段。
因此,它可以决定忽略active=true
(或更确切地说,不将新值发布到其他线程)。
您需要正确同步代码,在这种情况下,声明字段volatile
就足够了:
private volatile boolean active = false;
这可确保立即发布对此字段的所有更新,并且读取该字段的任何其他线程都将看到更新的字段。
我仍然不相信旋转外部过程会关闭,但这是另一回事。