2012-04-05 82 views
0

我有一個正在運行並重復執行任務的線程。我已經實現了一個計數器來顯示線程執行任務的迭代。我偶爾會發現櫃檯停滯不前,而且不再增加。我沒有收到任何錯誤或例外。應用程序運行,但它看起來像線程剛剛停止沒有我問。線程無法停止

我將添加一些代碼來顯示線程執行:

通知INT「C」 - 多數民衆贊成迭代計數器。

public void check() { 
    Thread check = new Thread() { 
     public void run() { 

      for (;;) { 
       EventQueue.invokeLater(new Runnable() { 
        public void run() { 
         // Update GUI here on EventQueue. 

         try { 
          Task.readTasks(); 
         } catch (InvalidFormatException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } catch (IOException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 

         if (NoteInfo == null || NoteInfo == "") { 
          btnViewNote.setEnabled(false); 
         } else { 

          btnViewNote.setEnabled(true); 
         } 

         textField.setText(Task.printNextTask); 
         c++; 
         lblCycle.setText("Cycle: " + c); 

        } 
       }); 

       try { 
        Thread.sleep(5000); 
        // Task.initializeIt(); 
       } catch (InterruptedException ie) { 
        break; 
       } 
       if (killcheck) 
        break; 

      } 
     } 
    }; 
    check.start(); 
} 

public static void stopChecking() { 
    killcheck = true; 
    progressBar.setValue(0); 
    textArea.setText(""); 
    textField.setText(""); 
    c = 0; 
    lblCycle.setText("Cycle: " + c); 

} 
+0

我把打印語句休息前看到沒線程結束。我還會在C++語句之前放置一個print語句。當計數器停止增加時,我也會啓動調試器並掛起線程。 – Alvin 2012-04-05 09:14:27

回答

1

檢查線程被另一個線程中斷。打印catch塊中的堆棧跟蹤並驗證它。

try {  
     Thread.sleep(5000); 
     // Task.initializeIt(); 
    } catch (InterruptedException ie) {  
      // break;   // just ignore it 
    } 
+2

永遠不要忽略InterruptedException。 http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html – artbristol 2012-04-05 08:54:31

+0

這似乎不是問題,我做了你所說的並且堆棧跟蹤不被打印。 – Yosi199 2012-04-05 08:57:03

+0

@artbristol:至少在這種特殊情況下,'killCheck'變量用於此目的。 +1。 – 2012-04-05 08:58:53

0

我沒有看到killcheckc的定義,但有可能這些都沒有被標記爲volatile

如果多個線程正在讀取和寫入共享值,那麼必須有某種同步,否則它們可能會處理過時的值。您可以使用其中一個原子類,如AtomicBooleanAtomicInteger,使用​​關鍵字,或將該變量標記爲volatile。所有這三個將允許主線程和內部線程看到對方對共享字段的更改。

volatile int c; 
volatile boolean killcheck; 

對於後人,這裏是你如何使用原子類:

final AtomicInteger c = new AtomicInteger(); 
final AtomicBoolean killcheck = new AtomicBoolean(); 
... 
     c.incrementAndGet(); 
... 
     if (killcheck) 
      break; 
... 
     killcheck.set(true); 
... 
     c.set(0);