当第一个问题出现时我启动计时器,它会回来。如果用户及时回答问题,我希望计时器完全取消并启动新的计时器。但是,当用户回答问题时,在第二个问题中,第一个计时器仍在处理。
这是我的计时器方法:
public Timer myTimer() {
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
sec--;
if (sec<0) {
this.cancel();
game.dispatchEvent(new WindowEvent(game, WindowEvent.WINDOW_CLOSING));
JOptionPane.showMessageDialog(null, "GAME OVER!\nYour score: " + score);
scoreJSON = new ScoreJSON(playerName, score);
scoreJSON.write();
} else if (sec<10) {
time.setText("0" + String.valueOf(sec));
} else {
time.setText(String.valueOf(sec));
}
}
};
timer.schedule(timerTask, 1000, 1000);
return timer;
}
这是用户回答问题的另一种选择:
a.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
checkAnswer("answer0");
myTimer();
}
});
答案 0 :(得分:1)
我重新设计了myTimer()
方法,发现在cancel()
实例(而不是Timer
)上调用TimerTask
会正确停止计时器。发生这种情况是因为在cancel()
上调用TimerTask
可能会取消任务,但不会取消计时器。下面的代码显示了我用来测试的类。
public class TimerTest {
public static final int TIMEOUT = 5;
private static Timer timer;
public static void main(String[] args) {
// Creates and starts the Timer. The TimerTask cancels the Timer when
// it's done, so we don't need to keep a reference to it.
timer = myTimer(TIMEOUT);
try {
// Suppose the correct answer is given after 2.5 seconds
Thread.sleep(2500);
} catch (InterruptedException e) {
}
timer.cancel();
System.out.println("Timer interrupted by main");
}
public static Timer myTimer(final int timeout) {
// We keep the Timer instance with the TimerTask, to prevent us from
// having to worry about managing multiple timers. Each Timer is
// guaranteed to stop when sec drops to 0.
final Timer t = new Timer();
TimerTask timerTask = new TimerTask() {
// We keep the current time in each TimerTask. This ensures that
// multiple TimerTasks will not interfere with each other.
private int sec = timeout;
@Override
public void run() {
sec--;
if (sec < 0) {
t.cancel(); // cancel the Timer here.
System.out.println("Timer stopped by TimerTask");
} else {
// Replace this with whatever you do each second
System.out.println("Current time: " + (sec < 10 ? "0" : "") + sec + " seconds");
}
}
};
t.schedule(timerTask, 1000, 1000);
return t;
}
}
运行该示例启动一个Timer,然后在2.5秒后停止它(这也会退出JVM,因为没有更多正在运行的线程)。将TimerTask中的t.cancel()
更改为this.cancel()
似乎取消了该任务(不再打印任何内容),但无法取消定时器(JVM继续运行)。
答案 1 :(得分:0)
你需要有办法安全地停止线程。看看这个选项:The Safe Way to Stop a Thread by Bruce Eckel。这样,您可以在正在运行的计时器线程上调用requestStop,然后启动一个新线程。您必须保存对您启动的每个计时器线程的引用,以便稍后可以在其上调用.requestStop方法。