多线程处理和中途停止

问题描述:

我在停止中间线程时遇到问题。这是我的代码的一部分,在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(); 
     }   
    } 
} 

您的代码被写入的方式,线程正在休眠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