2014-10-30 42 views
1

我想弄清楚線程是如何在Java中工作的。我想了解如何中斷創建的線程來運行另一個終端進程。我有以下主題:如何中斷/終止Java中的掛起線程?

  • 主線程
  • Swing線程 - 管理GUI
  • 終端紗線 - 運行終端處理

終端處理需要將其輸出饋送到終端線程的輸入流。我設法通過一個while循環做到這一點。但是,如果終端進程卡住了(例如等待用戶輸入),那麼這樣做實際上會掛起線程。

我的問題是雙重的:

  1. 如何中斷終端線程? (請參閱下面的代碼)
  2. 如果我通過main和swing線程關閉我的應用程序,這會關閉終端線程嗎?我一直以這種方式關閉我的應用程序......幽靈線程是否繼續運行?如果是這樣,我該如何驅邪呢?

下面的代碼是一個可運行的執行要運行的輪流運行終端處理線程:

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); 
    } 
}); 

回答

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()僅作爲最後的手段。

+0

謝謝。這個竅門!你能否就這個問題的第二部分提出建議?如果我不關閉線程而退出程序,它們會繼續運行嗎?假設我用system.Exit(0)退出。 – user3804927 2014-10-30 22:31:03

+0

我已經添加了一個解釋。 – 2014-10-30 22:43:13

+0

謝謝。我會贊成,但我還沒有足夠的代表。我會在我做的時候重新審視。謝謝! – user3804927 2014-10-30 22:47:03

0

變化的條件你的while循環:

while ((line = in.readLine()) != null && !Thread.currentThread().isInterrupted()) { 
    System.out.println(line); 
} 
+0

試過了,依然不行。 – user3804927 2014-10-30 08:18:46