Java 正在创建计时器,但无法重新启动它
我已经创建了GUI定时器,它完全按照我想要的方式运行。我有一个停止和暂停按钮,当我停止或暂停计时器并重新启动一个新的计时器时,我在线程AWT-EventQueue-0 java.lang.IllegalStateException中得到异常:任务已计划或已取消 我不确定我该怎么做我听说你不能重用任务,但我没有解决这个问题的线索。有人能帮我一下吗?我快疯了,我似乎总是能解决一个问题,但另一个问题突然出现 这是我倒计时的部分代码Java 正在创建计时器,但无法重新启动它,java,timer,Java,Timer,我已经创建了GUI定时器,它完全按照我想要的方式运行。我有一个停止和暂停按钮,当我停止或暂停计时器并重新启动一个新的计时器时,我在线程AWT-EventQueue-0 java.lang.IllegalStateException中得到异常:任务已计划或已取消 我不确定我该怎么做我听说你不能重用任务,但我没有解决这个问题的线索。有人能帮我一下吗?我快疯了,我似乎总是能解决一个问题,但另一个问题突然出现 这是我倒计时的部分代码 private TimerTask task = new Timer
private TimerTask task = new TimerTask(){
@Override
public void run(){
if (countdown()) {
if(minutes < 9 && seconds < 9)
timerOutput.setText("0"+minutes + ": 0" + seconds);
else if(minutes < 9)
timerOutput.setText("0"+minutes + ":" + seconds);
else if(seconds < 9)
timerOutput.setText(minutes + ": 0" + seconds);
}
else
{
System.out.println("Finish!");
timerOutput.setText("Time is up!");
timer.cancel();
startBut.setEnabled(true);
}
}
})
嗯,TimerTask的设计不是为了重用。您所能做的最好的事情就是在每次重新安排时间时创建一个新的TimerTask。尽管您不能简单地重新启动计时器,但您可以创建一个计时器包装类,它的行为与计时器完全相同,但允许一个简单的重新启动方法在后台实例化一个新计时器。比如,
public class RestartableTimer{
private Timer timer;
private long delay, period;
public RestartableTimer(){
timer = new Timer();
}
public void scheduleAtFixedRate(TimerTask task, long delay, long period){
this.delay = delay;
this.period = period;
timer.scheduleAtFixedRate(task, delay, period);
}
public void restart(TimerTask task){
timer.cancel();
timer = new Timer();
timer.scheduleAtFixedRate(task, delay, period);
}
}
一个公平的警告,这将不允许多态性。例如,您不能在计时器引用中存储RestartableTimer。重新启动时,您还需要实例化一个新的TimerTask。如果您想要并且知道只会重用相同的TimerTask,那么可以在上面声明一个自定义的私有嵌入类,并让包装器类处理新TimerTask的创建。或者,您可以让类方法采用TimerTaskFactory,它将实现一个接口,该接口需要一个返回TimerTask的方法
下面是使用上述类的示例
public static void main(String[] args) throws InterruptedException{
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println("Running");
}};
RestartableTimer rt = new RestartableTimer();
System.out.println("Timer starting with one task");
rt.scheduleAtFixedRate(task, 1000, 1000);
Thread.sleep(5000);
System.out.println("Timer restarting with another task");
rt.restart(new TimerTask(){
int count = 0;
@Override
public void run() {
if(count>4) {
System.out.println("Done");
this.cancel();
} else {
System.out.println("Running 2");
count++;
}
}});
}
最好的方法是什么,这取决于你的课程是如何组织的,但只要在每次重新安排课程时创建一个新的课程就行了。如果需要重复部分代码,请将run方法中的代码设置为单独的方法,并在run方法中调用它以避免重复。
public static void main(String[] args) throws InterruptedException{
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println("Running");
}};
RestartableTimer rt = new RestartableTimer();
System.out.println("Timer starting with one task");
rt.scheduleAtFixedRate(task, 1000, 1000);
Thread.sleep(5000);
System.out.println("Timer restarting with another task");
rt.restart(new TimerTask(){
int count = 0;
@Override
public void run() {
if(count>4) {
System.out.println("Done");
this.cancel();
} else {
System.out.println("Running 2");
count++;
}
}});
}