Вызов и использование метода .interrupt()?

Как именно мне вызвать метод .interrupt()? Когда у меня есть Thread.sleep(1000), когда и где мне вызывать метод .interrupt()? это после? Что я хочу сделать, так это остановиться Thread.sleep(1000) на полпути.

РЕДАКТИРОВАТЬ::

у меня проблемы с остановкой потока в середине. Это часть моего кода, в классе StoplightThread у меня проблемы с первым оператором if. Предполагается, что он должен подождать не менее 10 секунд, а затем позволить пользователю нажать кнопку, чтобы он мог изменить свет, если кнопка нажата, она должна остановить текущий поток в этом случае Thread.sleep(40000). Что происходит, когда я нажимаю кнопку, она меняет свет, но не останавливает нить. Если я нажму кнопку, пока осталось 20 секунд, это добавит 20 секунд к 10 секундам для желтого света, сделав его желтым на 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();
        }           
    }
}

person FJam    schedule 13.05.2013    source источник


Ответы (3)


Если бы вы вообще собирались вызывать interrupt(), вы бы вызывали его из другого потока, а не из sleep().

Если вы хотите прервать sleep() на полпути из того же потока, вы можете сделать это:

   Thread.sleep( 500 );
   ... 
   Thread.sleep( 500 );

Все это говорит о том, что sleep() может быть запахом кода.

EDIT (после редактирования OP):

Вызовите interrupt() для StoplightThread из потока GUI в методе actionPerformed().

person Andy Thomas    schedule 13.05.2013
comment
ну не совсем середина. Так что мне нужно создать новую тему, чтобы остановить это? - person FJam; 14.05.2013
comment
Вы хотите, чтобы он останавливался по истечении определенного периода времени или при возникновении события? - person Andy Thomas; 14.05.2013
comment
Один поток не может делать две вещи одновременно. Если вы решили заставить его спать, оно спит. Пока не истечет время ожидания. Если вы не хотите так долго спать, просто уменьшите время ожидания. - person JB Nizet; 14.05.2013
comment
Предположительно, вы хотите остановить его, потому что что-то произошло - пользователь нажал кнопку или вернулся асинхронный вызов, или... Что бы это ни было, оно должно исходить из другого потока, если вы все правильно настроили. В этом потоке вы прервете свой спящий поток. Может быть, вы могли бы предоставить более подробную информацию о том, что вы делаете. - person atw13; 14.05.2013
comment
@FJam: если событие получено и обработано, оно передается другим потоком. Поток не может одновременно спать и обрабатывать событие. Поэтому прервите спящий поток из потока обработки событий. - person JB Nizet; 14.05.2013
comment
Хорошо, тогда вам нужно что-то, чтобы обнаружить, когда событие произошло. Это не может быть поток, который спит(), потому что он спит. Так что либо это должен быть другой поток, либо вы должны заблокировать тот же поток, пока не произойдет событие. - person Andy Thomas; 14.05.2013
comment
поэтому в коде, который у меня есть прямо сейчас, мне нужно создать еще один класс потоков? - person FJam; 14.05.2013
comment
Нет, если вы можете использовать поток, который запустил StoplightThread, который, вероятно, является потоком графического интерфейса. - person Andy Thomas; 14.05.2013

попробуйте этот пример

public class Test1 {

    public static void main(String[] args) throws Exception {
        Thread t = new Thread() {
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t.start();
        Thread.sleep(1000);
        t.interrupt();
    }
}

он печатает

java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at test.Test1$1.run(Test1.java:9)
person Evgeniy Dorofeev    schedule 13.05.2013
comment
подождите, я запутался... почему Thread.sleep(2000); запускается? это был t.start(), который был вызван впоследствии. - person FJam; 14.05.2013
comment
t.start() вызывается ниже в файле определения анонимного класса, чей метод run() вызывается в результате t.start(), что приводит к вызову Thread.sleep(2000). - person Andy Thomas; 14.05.2013
comment
когда мы создаем новый поток, это просто объект, который еще не работает. когда мы вызываем t.start(), JVM вызывает свой метод run() в параллельном потоке - person Evgeniy Dorofeev; 14.05.2013

Вам нужна ссылка на поток, который вы хотите прервать, чтобы вы могли вызвать interrupt() для него из другого потока.

person Adam Siemion    schedule 13.05.2013