2013-05-13 108 views
0

我在停止中間線程時遇到問題。這是我的代碼的一部分,在StoplightThread類中,我對第一個if語句有問題。它應該做的是等待至少10秒,然後允許用戶按下按鈕,以便他們可以改變光線,如果按下按鈕,則應當停止正在運行的線程,在這種情況下,Thread.sleep(40000)。發生什麼事是當我按下按鈕時它改變光線但不停止線程。如果我在按住按鈕的同時仍有20秒左右的時間,它會在10秒內爲黃燈增加20秒,使它變黃30秒。多線程處理和中途停止

編輯:如果您想知道,stoplightCanvas.x == 3是綠色,stoplightCanvas.x == 2是黃色,stoplightCanvas.x == 1是紅色。

class StoplightCanvas extends Canvas implements ActionListener 
{ 

    public void actionPerformed(ActionEvent e) 
    { 
     if (e.getSource() == cross) { 
      isPressed = true; 
      if (x == 3 && canCross) 
       x = 2;  
     } 
     repaint(); 
    } 

} 


class StoplightThread extends Thread 
{ 
    StoplightCanvas stoplightCanvas; 

    StoplightThread(StoplightCanvas stoplightCanvas) { 
     this.stoplightCanvas = stoplightCanvas; 
    } 

    public void run() 
    { 
     if (stoplightCanvas.x == 3){ 
       Thread.sleep(10000); 
       stoplightCanvas.canCross = true; 
       Thread.sleep(40000); 
       if(stoplightCanvas.isPressed) 
        StoplightThread.interrupt(); 
      } else if (stoplightCanvas.x == 2) { 
       Thread.sleep(10000);  
      } else if (stoplightCanvas.x == 1) { 
       Thread.sleep(60000); 
      } 
     } catch (InterruptedException e){} 

      stoplightCanvas.toggleColor(); 
      stoplightCanvas.repaint(); 
     }   
    } 
} 

回答

0

您的代碼被寫入的方式,線程正在休眠40秒;然後喚醒並檢查stoplightCanvas.isPressed並設置中斷標誌...

如果要在線程休眠期間中斷線程,則需要從另一線程中斷線程。 EventDispatchThread是做這件事的好地方,所以你可以修改你當前的ActionListener,或者創建另一個。

public void actionPerformed(ActionEvent e) 
    { 
     ... 
     stopLightThread.interrupt(); 
    } 

如果你不希望暴露stopLightCanvas外鍵,那麼您可以在StopLightCanvas推出自己的監聽器支持:

class StopLightCanvas extends Canvas implements ActionEventListener { 
    public static interface StopLightListener extends EventListener { 
    public void stopLightChanged(int state); 
    } 

    // watch out, you may need this to be threadsafe depending on your usage 
    List<ActionEventListener> myListeners = new LinkedList<StopLightListener>(); 
    public void addStopLightListener(StopLightListener lst) { 
    myListeners.add(lst); 
    } 

    public void actionPerformed(ActionEvent e) { 
     if (e.getSource() == cross) { 
      isPressed = true; 
      if (x == 3 && canCross) 
       x = 2;  
     } 
     repaint(); 

     for(StopLightListener lst: myListeners) { 
      lst.stopLightChanged(x); 
     } 
    } 

    ... 
} 

public class StopLightThread extends Thread implements { 
    StoplightThread(StoplightCanvas stoplightCanvas) { 
     this.stoplightCanvas = stoplightCanvas; 
     stopLightCanvas.addStopLightListener(this); 
    } 

    ... 

    @Override public void stopLightChanged(int state) { 
     this.interrupt(); 
    } 
} 
+0

我先看看,如果按下按鈕,然後嘗試做'StoplightThread.interrupt();' – FJam 2013-05-13 20:40:51

+0

當我嘗試執行'StoplightThread.interrupt();'我得到這個錯誤:'非靜態方法中斷()不能從靜態上下文中引用' – FJam 2013-05-13 20:42:11

+0

您正在從線程班是的?你讀過關於「這個」和「超級」的關鍵詞嗎? – ObedMarsh 2013-05-13 20:45:14