MultiThread处理和中途停止

时间:2013-05-13 20:22:03

标签: java multithreading

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

1 个答案:

答案 0 :(得分: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();
    }
}