2010-02-23 1 views
1

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

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. Используйте флаг: Но проблема в том, что если resumeCalculating() принимает (EDIT: долгое время) навсегда до конца?
  2. Включить исключение в калькулятор, как?
  3. Могу ли я использовать прослушиватели событий или что-то еще? Я думал, что они использовались для графических интерфейсов
  4. Просто остановите его? И Class Thread включает какой-то деконструктор, который будет вызываться, когда поток прекращается, и я мог бы обработать там?

EDIT Владелец:

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

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(); между каждой линией практической или красивая? Я просто хочу отбросить полученные результаты и сохранить предыдущие результаты.

ответ

5

Правильный способ, чтобы остановить поток является interrupt это.

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

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

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

Да, я думаю, что это ответ, большое спасибо – TiansHUo

+0

, просто не забывайте, что 'interrupted()' также очищает * прерванный статус *, поэтому последующие вызовы возвращают 'false'. –

0

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

+0

Да я могу обрабатывать флаг прерывания в resumeCalculating(), но это не так хорошо, я хотел бы, чтобы это было. resumeCalculating должен заботиться только о вычислении ИП, а не о том, как он должен умереть. Этот код был бы лучше всего в потоке калькулятора. А что, если бы у меня было много шагов? – TiansHUo

0

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

0

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