Остановить таймер в пакете OSGI

Итак, у меня есть пакет OSGi, который создает такой таймер ...

       Timer timer = new Timer(true);
       // running timer task as daemon thread
       timer.scheduleAtFixedRate(this, 0, 2 * 1000);//my class extends the timer task 
       // cancel after 60s
        try 
        {
           Thread.sleep(60000);
        } 
        catch (InterruptedException e) 
        {
           e.printStackTrace();
        } 
        finally 
        {
           timer.cancel();
        }

Это работает нормально, пока пакет OSGi не остановлен до завершения задачи таймера. Если я попытаюсь остановить пакет до истечения времени ожидания таймера (например, 60 с), я получаю исключение, что пакет не может быть остановлен чисто.

В моем методе деактивации пакета я отменяю таймер, но я предполагаю, что, поскольку поток спит, остановка пакета не вызывается до истечения времени ожидания

Я просто хотел понять, есть ли способ остановить пакет до истечения времени ожидания, который также убьет задачу таймера?


person user2912902    schedule 05.03.2015    source источник


Ответы (1)


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

Опубликованный вами код должен выполняться в отдельном потоке, и вам необходимо сохранить ссылку на этот поток. Когда пакет деактивирован, отправьте прерывание этому потоку, используя _ 1_. Ваш код уже будет работать, но, вероятно, не захочет распечатывать трассировку стека. Вот пример:

cancelTimerThread = new Thread() {
    public void run() {
        try {
            Thread.sleep(60000);
        } 
        catch (InterruptedException e) {
            log.debug("timer canceled by bundle stop");
        }
        timer.cancel();
    }
}
cancelTimerThread.start();

При деактивации пакета:

public void stop() {
    // signal thread to cancel timer early
    cancelTimerThread.interrupt();
}

Помните, что при использовании timer.cancel() текущая задача таймера не будет прервана. Если бы это была длительная задача, вам, вероятно, следовало бы отправить прерывание и этой задаче.

person kapex    schedule 06.03.2015
comment
но не следует ли thread.sleep () генерировать InterruptedException, когда пакет остановлен? ... я изменил код, чтобы отменить таймер в блоке catch прерывания interruptedexception, но я все равно получаю ту же ошибку ... пакет не может быть остановлен чисто - person user2912902; 06.03.2015
comment
@ user2912902 Должен, если вы вызовете interrupt(), но не произойдет автоматически. cancel по-прежнему нужно вызывать после try / catch, а не только внутри блока catch - в случае, если засыпание завершается без прерывания. - person kapex; 06.03.2015