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

1 回答 1

0

您的代码编写方式,线程休眠 40 秒;然后唤醒并检查stoplightCanvas.isPressed并设置中断标志......

如果你想在线程睡眠时中断它,你需要从另一个线程中断。EventDispatchThread 是执行此操作的好地方,因此您可以修改当前的 ActionListener,或者创建另一个执行此操作的 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();
    }
}
于 2013-05-13T20:37:13.767 回答