2012-03-20 2 views
0

Я стучу головой о стол, здесь друзья. Это то, что я пытаюсь выполнить. У меня есть класс Main, который создаст новый поток. Прямо сейчас, когда поток будет работать, он выполнит незначительную очистку, и поток остановится. Тем не менее, у меня есть кнопка «Стоп» в пользовательском интерфейсе, которая при нажатии должна «сделать некоторую очистку, а затем убить поток». Проблема в том, что я не могу обновить что-либо, что находится внутри этого нового потока, который я создал .Java - Невозможно остановить выполнение из основного класса

Вот некоторые фрагменты:.

Main Class

runner = new Thread(new Controller1(options)); 
runner.start(); 

в приведенном выше коде, я звоню класс Controller1 и установить некоторые "варианты" в конструкторе Это работает хорошо до сих пор ...

Теперь, в классе Controller1, это значение t I have ...

public volatile static boolean stopped; 

public void run() { 
    while(!stopped){ 
     System.out.println("In run"); 
     startProxy(proxyPort); 
     startWebDriver(); 
     driver.get(http); 
     UIMainJSwing1.updateStartButton(); 
     stopped=true; 
    } 

    //Run killAll to stop webdriver and the proxy 
    killAll(); 
    System.out.println("Thread complete"); 
} 

Проблема в том, что из класса Main я не могу позвонить или установить «остановлен» на true. Я могу вызвать runner.interrupt(), но проблема в том, что, поскольку поток просто умирает, моя функция killAll() никогда не запускается, и я остаюсь с запущенным WebDriver и прокси.

+0

Хорошая точка в цикле While, я думаю, я положил ее туда, потому что я пытался найти способ остановить эту тему от моего Main. Теперь, когда я его удалил, да, он запускается один раз, но есть ли у него переопределение, которое выведет его из метода run() и в killAll()? – Whnunlife

+0

Любые блокирующие вызовы в этом цикле? – Tudor

+0

@Whnunlife Если вы найдете какой-либо ответ полезным, вы должны его перенести и/или принять, т.е. Грей ответил. –

ответ

1

Я бы назвал thread.interupt() в основном потоке и использовать в try/finally block вокруг петли в вашем Runnable, чтобы убедиться, что ваш метод killAll() называется.

public void run() { 
    try { 
     while (!stopped) { 
      ... 
     } 
    } finally { 
     //Run killAll to stop webdriver and the proxy 
     killAll(); 
     System.out.println("Thread complete"); 
    } 
} 

Окончательно блок будет всегда называться. Даже если поток прерывается или генерирует исключение.

Пара Другие комментарии:

И вы упоминаете volatile boolean stopped флаг, но вы устанавливаете, что немедленно быть верным в конце цикла, так что я понимаю, почему у вас есть цикл вообще.

Предполагая, что нить не проходит и сразу вызывает killAll(), тогда она висит где-то в одном из методов. Когда вы вызываете interrupt() из основного потока, все, что ждет, будет кидать InterruptedException. Но так как я не вижу никаких попыток, возможно, методы перебрасывают его как RuntimeException? Они должны, по крайней мере, делать что-то вроде следующего, но это по-прежнему блокирует исключение:

try { 
    something.wait(); 
} catch (InterruptedException e) { 
    // restore the interrupted condition 
    Thread.currentThread().interrupt(); 
} 

Независимо попытка/наконец, это правильный путь, чтобы обеспечить killAll называется.

+0

'catch (InterruptedException e) { // восстановить прерванное условие Thread.currentThread(). Interrupt(); } 'это все еще может быть исключение, если оно находится в некотором' while (true) 'loop – artbristol

+0

True @artbristol. Я изменил свой ответ. Благодарю. – Gray

+0

Вопрос, этот try/catch, который должен идти в методе run() моего runnable правильно? – Whnunlife

0

Во-первых, вы должны, вероятно, поймать InterruptedException, чтобы ваш метод killAll() запускался. Просто попробуйте/наконец

Во-вторых, почему вы не можете установить stop = true из вашего основного метода?

+0

Я пробовал это, поэтому то, что я сделал, чтобы проверить это, было внутри run(), удалил stop = true в конце инструкции while. Поэтому, если я запустил его, это всего лишь цикл. Затем я попытался установить это значение из Main при нажатии на кнопку, но цикл никогда не выходит. – Whnunlife

+0

, если вы посмотрите на код, который использует «прерванный», вы увидите, что в методе run() он проверяет, прервано ли true, и выбрасывает InterruptedException. Точно так же, как вы остановились == true. Дело в том, что вы ни в коем случае не можете прервать работу нитки силой из другого потока. Вы должны проверить свой код в run() в любой момент, если выполнение все еще должно выполняться. Если нет - выйдите или выбросьте InterruptedException. Все сами :) Вместо остановки вы можете использовать метод isInterrupted(), который присутствует в классе Thread, и вызвать прерывание() из основного потока. – yggdraa

+0

Спасибо за информацию там, поэтому у меня должно быть некоторое время (! IsInterrupted()) Тогда, если я вызову thread.interrupt, он получит проверку как истину и поймается правильно? – Whnunlife

0

Если я понимаю, что правильно, вы злоупотребляете идиомой (!). В вашем коде вы проверяете, не остановился ли он один раз, а затем выполните все до конца, установите stop = true и выйдите. Вы просто не можете прекратить выполнение после его запуска. Когда он запустит, остановленное поле никогда не будет перенаправлено, пока оно не закончится.

+0

Вы правы, обращаясь сейчас! – Whnunlife

0

Во-первых, потеряйте while(!stopped) и stopped=true частей. Также вам нужно оценить stopped на каждом отдельном этапе в потоке (и не забудьте запустить killAll() и снова включить кнопку запуска).

+0

Я изменил метод run() и обернул каждую функцию в if (! Остановлен), таким образом, если я установил stop = true из моего основного, следующая функция не будет запущена и вызывается killAll. Думаю, у меня это работает, похоже на любительский код, но хорошо. – Whnunlife

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