Пробуждение спящего потока - прерывание () против «разделения» сна на несколько снов

Это требование появилось в моем приложении для Android, но в целом относится к Java. Мое приложение «что-то делает» каждые несколько секунд. Я реализовал это следующим образом (только соответствующие фрагменты - не полный код):

Snippet1:

public class PeriodicTask {

    private boolean running = true;
    private int interval = 5;

    public void startTask(){
        while (running){
            doSomething();
            try{
                Thread.sleep(interval * 1000);
            } catch(InterruptedException e){
                //Handle the exception.
            }
        }
    }

    public void stopTask(){
        this.running = false;
    }

    public void setInterval(int newInterval){
        this.interval = newInterval;
    }
}

Проблема с этим подходом, как вы можете видеть, состоит в том, что setInterval () не сразу эффективен. Он вступает в силу только после завершения предыдущего сна ().

Поскольку мой вариант использования позволяет конечному пользователю устанавливать интервал фиксированными шагами (от 1 секунды - от 1 до 60 секунд), я изменил реализацию так, чтобы она спала в цикле; и проверять новое значение интервала каждую секунду следующим образом:

Snippet2:

public class PeriodicTask {

    private boolean running = true;
    private int interval = 5;
    private int loopCounter = 0;

    public void startTask(){
        while (running){
            doSomething();
            try{
                while(loopCounter < interval) {
                    Thread.sleep(1 * 1000);
                    loopCounter ++;
                }
            } catch(InterruptedException e){
                //Handle the exception.
            }
        }
    }

    public void stopTask(){
        this.running = false;
    }

    public void setInterval(int newInterval){
        synchronized (this) {
            this.interval = newInterval;
            if(newInterval < loopCounter){
                loopCounter = 0;
            }
        }
    }
}

Есть ли причина не использовать этот подход?

Я недавно натолкнулся наinterrupt() метод для этой цели. Но я не мог точно понять, как его использовать. С одной стороны, метод прерывания, в отличие от метода сна, неstatic, И чтоThread мне перебить?

public void setInterval(int newInterval){
        this.interval = newInterval;
        //What thread do I call interrupt() on?
    }

Во-вторых, если мне удастся прервать сонThreadЯ верюcatch блок дляInterruptedException будет выполнен. Тем не менее, мне нужно будет позвонитьstartTask() снова в этот момент. Я смущен относительно прекращения этой рекурсии. Я прошел через несколько вопросов по SO относительно использования interrupt (), но не смог понять ничего, что мне помогло.

Есть указатели?

РЕДАКТИРОВАТЬ- Более подробную информацию о точном требовании:

Мое приложение выбирает некоторые значения, используя вызов REST каждые несколько секунд. Интервал обновления настраивается пользователем.

Теперь, скажем, интервал обновления был установлен на 60 секунд. Snippet1, который я разместил, будет работать (неправильно) следующим образом:

Поток засыпает на 60 секунд.Допустим, пользователь изменяет интервал обновления до 5 секунд. Нить все еще спит.PeriodicTask будет видеть новый интервал обновления только после истечения 60 секунд.

Точное требование заключается в том, что новые интервалы обновления должны вступать в силу немедленно (или, по крайней мере, не позднее, чем через 1 секунду после установки - так как это то, что пользователь, скорее всего, воспримет в любом случае).

Мои Snippet2 и Snippet3 являются попытками выполнить это требование.

Ответы на вопрос(4)

Ваш ответ на вопрос