Итак, у меня есть пакет 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 с), я получаю исключение, что пакет не может быть остановлен чисто.
В моем методе деактивации пакета я отменяю таймер, но я думаю, так как поток спящий, остановка пакета не вызывается до тайм-аута
Я просто хотел понять, есть ли способ остановить пакет до таймаута, который также убьет задачу таймера?
Вы можете использовать прерывания для отмены потоков. OSGi не отличается от других приложений, когда речь идет о параллелизме.
Код, который вы опубликовали, должен запускаться в отдельном потоке, и вам нужно сохранить ссылку на этот поток. Когда пакет деактивирован, отправьте прерывание в этот поток с помощью Thread.interrupt()
код действительно будет работать, но, вероятно, не хочет печатать трассировку стека. Вот пример:
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()
текущая задача таймера запуска не прерывается. Если это была долгая задача, вы должны, вероятно, отправить прерывание на эту задачу.
interrupt()
, но это не произойдет автоматически.cancel
все еще должна вызываться после try / catch, а не только внутри блока catch - в случае, если сон завершается без прерывания.