2015-01-02 5 views
0

Пожалуйста, помогите мне с моей проблемой. У меня есть 2 JMenuItems, если я нажму на Start, он начнется и начнет работать. Если я нажму «Стоп», он остановится :) После того, как я нажал кнопку «Старт», я нажимаю «Остановить», а иногда останавливается, а иногда нет. Но я хочу, чтобы он всегда останавливался.Тема Прерывание иногда работает, а иногда нет

Что я сделал не так? :/

class DiashowListener implements ActionListener { 
Thread td; 
boolean ok = false; 

     public void actionPerformed(ActionEvent e) { 

      if (e.getActionCommand().equals("Start")) { 

       td = new Thread(new Runnable() { 
        public void run() { 
         if (bimg != null) { 
           while (!ok) { 
            try { 
             ... 


            } catch (Exception e2) { 
            } 
            frame.repaint(); 
           }      
         } 
        } 
       }); 

       td.start(); 

      } else if (e.getActionCommand().equals("Stop")) { 
       if (td != null){ 
        ok = true; 
       } 
      } 
     } 
} 

EDIT: хорошо я что-то изменилось, его работы сейчас, но: Если я нажимаю на Stop он должен немедленно прекратить.

+0

Просто догадайтесь: попробуйте создать экземпляр td где-то вне actionPerformed. Как сейчас, существует риск (возможно), что td ссылается на совершенно новый поток. Изменить: также в «Стоп»: td.interrupt(); и, более того, см. ответ Димы .... –

ответ

1

Прежде всего, вы прерываете неправильную нить (должен быть td). Во-вторых, содержание оговорки try, которую вы опустили, действительно важно (некоторые операции являются бесперебойными). Наконец, Thread.isInterrupted скорее всего не то, что вы хотите использовать, так как флаг может быть очищен некоторым несвязанным кодом. В зависимости от того, что именно вы прерываете, он может (или не может) быть хорошей идеей просто поймать InterruptedException и прекратить работу в случае его броска. Лучше всего добавить свой собственный флаг, который будет проверяться потоком вместо isInterrupted, а обработчик события будет вместо (или в дополнение к) прерывать рабочий поток.

+0

В нормальном сценарии, когда td был запущен (и только начался один раз) Thread.currentThread() вернет td, исправьте? Или только если td фактически работает, а не во сне или какой-то блок? – Dtor

+0

№ 'Thread.currentThread()' возвращает ... ну, текущий поток. Один, который вызывает 'прерывание'. – Dima

+0

@SergWoron Что касается вашего редактирования. Ваша настройка/проверка флага 'ok' должна быть синхронизирована или, еще лучше, использовать' AtomicBoolean'. Если вы хотите, чтобы поток «немедленно останавливался», вам нужно чаще проверять флаг (и, опять же, опускаемое содержимое предложения 'try' действительно имеет значение здесь). Теперь, когда у вас есть это, поток прекратится, как только цикл завершится. – Dima

Смежные вопросы