У меня есть класс, в котором есть методы, запускающие и останавливающие таймер.
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest {
private Timer wrkTimer = new Timer(true);
public void StartWork() {
TimerTask wrkTask = new TimerTask() {
@Override
public void run() {
System.out.println("I'm working.");
}
};
wrkTimer.scheduleAtFixedRate(wrkTask, 0, 1000);
}
public void StopWork() {
wrkTimer.cancel();
}
}
В main я создаю второй таймер, который сначала останавливает, потом запускает заново таймер в TimerTest.
public class Main {
public static void main(String[] args) {
Timer wrkTimer1 = new Timer("timer1", true);
TimerTest tt = new TimerTest();
tt.StartWork();
TimerTask wrkTask1 = new TimerTask() {
@Override
public void run() {
tt.StopWork();
tt.StartWork();
}
};
wrkTimer1.scheduleAtFixedRate(wrkTask1, 0, 100);
}
}
При выполнении выдается исключение Exception in thread "timer1"
java.lang.IllegalStateException: Timer already cancelled.
Как я понял, исключение вызывается тем, что при остановке таймера из TimerTest через cancel() и при последующем запуске нужно заново создавать TimerTask, но разве в методе StartWork() TimerTask не создается заново?
TimerTask wrkTask = new TimerTask() {...};
Есть ли варианты как обойти данную проблему не меняя архитектуры программы? Или дело вообще не в TimerTask?
Во-первых, зачем вы создаёте daemon потоки, если по идее должны создавать user потоки? Советую прочитать вам вот эту статью.
Во-вторых, вы пересоздаёте wrkTask, но не пересоздаёте wrkTimer, из-за чего и вылетает исключение.
В-третьих, вам не нужно пересоздавать wrkTask, потому что это не имеет смысла.
Вот так должен выглядеть метод StopWorking():
public void StopWorking() {
wrkTimer.cancel();
wrkTimer = new Timer();
}