Как мне прекратить зацикленный подпоток в Java? - PullRequest
1 голос
/ 23 февраля 2010

Мне нужно выполнить некоторую работу по очистке, когда я собираюсь завершить зацикленную нить. Например, сохранение буфера, чтобы я мог продолжить позже.

PseudoCode: 
private class CalculatePI(Byte[] resume) implements Runnable{
    public void Run(){
       while(true){
          resume=resumeCalculating(resume);
       }
    }
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume)); 
Thread.sleep(200); 
//And now I want to kill calculator

Так, как лучше всего это реализовать?

  1. Использовать флаг: Но проблема в том, что если resumeCalculation () занимает (EDIT: длительное время) навсегда до конца?
  2. Поместите исключение в калькулятор, как?
  3. Могу ли я использовать прослушиватели событий или что-то еще? Я думал, что они были использованы для графических интерфейсов
  4. Просто прекрати это? И класс Thread включает в себя некоторый деконструктор, который будет вызываться, когда поток завершается, и я мог бы выполнить обработку там?

РЕДАКТИРОВАТЬ владельцем:

Я знаю, что могу использовать флаг. Но учтите это:

    public void Run(){
       while(true){
          resume=calculate_stepone(resume); //takes one minute
          resume=calculate_steptwo(resume); //takes two minutes
          resume=calculate_stepthree(resume); //takes three minutes
          resume=calculate_steplast(resume); //takes four minutes
       }
    }

Практически или красиво ставить if(flag) saveResultsAndExit(); между каждой строкой? Я просто хочу выбросить полуобработанные результаты и сохранить предыдущие.

Ответы [ 4 ]

5 голосов
/ 23 февраля 2010

Правильный способ остановить поток - это прерывание it.

Если задача, выполняемая в потоке, выполняет IO или использует sleep, то она получит сигнал (InterruptedException в этой точке); иначе задача должна регулярно опрашивать, чтобы узнать, прервана ли .

Позволяет адаптировать псевдокод оригинального плаката:

private class CalculatePI(Byte[] resume) implements Runnable{
    public void Run(){
       while(!Thread.interrupted()) { //###
          resume=resumeCalculating(resume);
       }
    }
}
Thread calculator= new Thread(new CalculatePI(Byte[] resume)); 
calculator.run(); //###
//...
//And now I want to kill calculator
calculator.interrupt(); //### sends the signal
//...
calculator.join(); //### actually waits for it to finish
0 голосов
/ 23 февраля 2010

Вероятно, лучше использовать флаг, подождать некоторое время до конца потока и, если он не (резюмеCalculation не вернул), завершить поток вручную. Вероятно, лучше не включать слишком много логики, основанной на потоках, в resumeCalculation, это действительно зависит от того, как она реализована, и от того, насколько легко ее прервать на полпути операции.

0 голосов
/ 23 февраля 2010

Создайте свою программу так, чтобы возобновление вычислений НЕ занимало вечность. Также синхронизируйте доступ к вашему флагу.

0 голосов
/ 23 февраля 2010

Ответ на 1 .: Вы также можете обработать флаг отмены в resumeCalculating().

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