Не останавливается поток

0
05 мар 2020 08:32
Hello, world!
У меня прога на JavaFX. В ней по кнопке СТАРТ запускается таймер, при этом кнопка меняет название на РЕСТАРТ с соответствующим функционалом.
Таймер в отдельно классе и запускается отдельным тредом. Остановку потока я прописываю с помощью логической переменной stop. Проблема в том, что поток не останавливается. При этом стартует ещё один такой же поток, работающий параллельно. Подскажите как сделать нормальный рестарт таймера.
Главный класс:
//Обработка событий кнопки СТАРТ
           public void handle(ActionEvent event){
                    btnStart.setText("RESTART");
                    hourCount.setText("0");     //обнуление лэйблов таймера
                    dayCount.setText("0");      //обнуление лэйблов таймера
                    
                    if (timerThread != null) {
                    timerClass.turnOff();
                    }

                    timerClass = new TimerClass(hourCount, dayCount);
                    timerThread = new Thread(timerClass);
                    timerThread.start();
                }        
            });


Класс таймера:
class TimerClass implements Runnable{
         
        Label labHour;
        Label labDay;
        private volatile boolean stop = false;
        
        public TimerClass(Label labH, Label labD) {
            labHour = labH;
            labDay = labD;
        }
             
        public void turnOff(){
            stop = true;
        }
        
        @Override
        public void run() {
            if(!stop){
            for (int y = 0;; y++){
            for (int i = 0; i <= 23; i++) {
                
                final int update_i = i;
                final int update_y = y;
                Platform.runLater(new Runnable(){
 
                    @Override
                    public void run() {
                        labHour.setText(Integer.toString(update_i));
                        labDay.setText(Integer.toString(update_y));
                        System.out.println(Integer.toString(update_y)+" "+Integer.toString(update_i));
                    }
                });
                 
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(TimerClass.class.getName()).log(Level.SEVERE, null, ex);
                  }
            }
            }
        } else {System.out.println("Timer thread has stopped.");}
        }
    }

Ответов: 1

0
05 мар 2020 11:09
if(!stop) - эта проверка должна быть внутри цикла. Твоя задача - выйти из всех циклов чтоб метод run() завершился как только переменная станет true.

Вместо того чтоб придумывать свои переменные следует использовать:
        if(Thread.currentThread().isInterrupted()){
            break;
        }

Ну и соответственно timerThread.interrupt() для изменения переменной. В итоге получаем:
public void handle(ActionEvent event){
        btnStart.setText("RESTART");
        hourCount.setText("0");     //обнуление лэйблов таймера
        dayCount.setText("0");      //обнуление лэйблов таймера

        if (timerThread != null) {
            timerThread.interrupt();
        }

        timerClass = new TimerClass(hourCount, dayCount);
        timerThread = new Thread(timerClass);
        timerThread.start();
    }

class TimerClass implements Runnable {

    Label labHour;
    Label labDay;
    private volatile boolean stop = false;

    public TimerClass(Label labH, Label labD) {
        labHour = labH;
        labDay = labD;
    }

    public void turnOff() {
        stop = true;
    }

    @Override
    public void run() {
        for (int y = 0; ; y++) {
            for (int i = 0; i <= 23; i++) {
                if (Thread.currentThread().isInterrupted())
                    return;
                final int update_i = i;
                final int update_y = y;
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        labHour.setText(Integer.toString(update_i));
                        labDay.setText(Integer.toString(update_y));
                        System.out.println(Integer.toString(update_y) + " " + Integer.toString(update_i));
                    }
                });

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(TimerClass.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
}
Модераторы: Нет
Сейчас эту тему просматривают: Нет