timertask в blackberry, изменить расписание по расписанию, не прерывая выполнение? - PullRequest
1 голос
/ 16 февраля 2011

Я использую TimerTask для запуска некоторого фонового процесса ..

schedule(TimerTask task, long delay, long period) 

Я хочу изменить значение длинного периода, не прерывая задачу, из следующего цикла выполнения следует использовать измененное время.

это возможно без прерывания или я должен отменить timerTask и перезапустить снова?

1 Ответ

0 голосов
/ 15 мая 2011

Я не думаю, что вы можете изменить интервал выполнения задачи, но я придумал это для решения проблемы.Это на самом деле консольная программа на Java (поскольку у меня есть только Linux, и я не могу использовать среду BlackBerry дома), и я использовал частные статические классы просто для того, чтобы она работала в одном файле, но я думаю, что идея должнабудьте вполне понятны:

import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;


public class Main
{
    public static void main(String[] args)
    {
        //Start a new task which runs every 1000ms
        TimerTest test = new TimerTest(1000L);
        TimerTaskStarter.startTask(test);

        //Wait for enter
        Scanner sc = new Scanner(System.in);
        while(!sc.nextLine().equals(""));

        //Change the interval (actually starts a new TimerTest after the current one runs next time)
        //since there's a new instance involved, the return value needs to be stored so it can be cancelled/controlled
        test = test.changeIntervalAtNextRun(500);

        //Wait for another enter        
        while(!sc.nextLine().equals(""));
        test.cancel();
        System.exit(0);
    }

    private static class TimerTaskStarter
    {
        public static void startTask(TimerTest task)
        {
            //Basic Timer-stuff
            Timer timer = new Timer();
            timer.schedule(task, task.getInterval(), task.getInterval());
        }
    }

    private static class TimerTest extends TimerTask
    {
        /**
         * Current interval
         */
        private long interval;

        /**
         * Flag to indicate interval change at next run
         */
        private boolean changeInterval;

        /**
         * The new instance running with the new interval once started
         */
        private TimerTest nextInstance;


        public TimerTest(long interval)
        {
            this.interval = interval;
            changeInterval = false;
        }

        @Override
        public void run()
        {   
            //The actual thing this task does goes here
            System.out.println("Running task");

            if(changeInterval == false)
            {
                //Not changing interval, just keep running
                System.out.println("Current interval is " + interval);
            }
            else
            {
                //Changing interval, cancel self and start new task
                System.out.println("Startingting new instance with interval " + interval);
                cancel();

                //Start a new task with new interval
                TimerTaskStarter.startTask(nextInstance);
            }
        }

        /**
         * Creates a new task with given interval. This task is cancelled and new task is automatically started
         * the next time this task runs
         * @param newInterval   Interval to run the new instance at
         * @return new TimerTest-instance
         */
        public TimerTest changeIntervalAtNextRun(long newInterval)
        {
            interval = newInterval;
            changeInterval = true;
            nextInstance = new TimerTest(interval);
            return nextInstance;
        }

        /**
         * Returns current interval
         * @return Interval as milliseconds
         */
        public long getInterval()
        {
            return interval;
        }
    }
}

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

Я сделал TimerTaskStarter.startTask статическим, просто для простоты, вполне может быть своего рода класс менеджера, содержащий все выполняющиеся в данный момент задачи, которые можно было бы пропуститьв TimerTest changeIntervalAtNextRun, и экземпляр TimerTest передаст новую задачу непосредственно ему.С несколькими потоками вам, вероятно, потребуется некоторая синхронизация, но в этом примере я ее не учел.Надеюсь, это поможет (хотя вопрос уже пару месяцев).

...