Java - Невозможно остановить работоспособный из основного класса - PullRequest
0 голосов
/ 20 марта 2012

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

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

Основной класс

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

В вышеприведенном коде я вызываю свой класс Controller1 и устанавливаю некоторые «опции» в конструкторе. Пока это работает хорошо ...

Теперь, в классе Controller1, это то, что у меня есть ...

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");
}

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

Ответы [ 4 ]

1 голос
/ 20 марта 2012

Я бы вызвал 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");
    }
}

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

Пара других комментариев:

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

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

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

Независимо от того, что try / finally - правильный путь, чтобы гарантировать, что killAll вызывается.

0 голосов
/ 20 марта 2012

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

0 голосов
/ 20 марта 2012

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

0 голосов
/ 20 марта 2012

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...