我一直在挠头,试图找出Java定时器的挂起问题。我想知道这里有人可以帮忙。高度赞赏任何帮助诊断问题。Java定时器挂起问题
我有一个简单的程序,有三个TimerTask类(A,B和Stopper)。 A和B分别每400ms和500ms反复运行。定时器任务计划在2秒内运行以关闭所有内容。计时器按预期启动,并且run()方法的任务按预期执行。但是,一旦停止任务执行,我希望程序终止,但它只是在打印“所有任务和定时器被取消,退出”后才挂起。我已经使用jstack来诊断问题尝试,但并没有什么明显的指示什么,如果有什么需要发布/停止/取消等
这里是我的代码:
package com.example.experiments;
import java.util.Date;
/**
* A test timer class to check behavior of exit/hang issues
*/
public class TimerTest {
TimerTest(){
}
class TaskA extends java.util.TimerTask {
TaskA(){
}
public void run() {
System.err.println("A.run() called.");
if (!running){
System.err.println("A: calling this.cancel().");
this.cancel();
return;
}
}
public boolean cancel(){
System.err.println("Canceling TaskA");
return super.cancel();
}
}
class TaskB extends java.util.TimerTask {
TaskB(){
}
public void run(){
System.err.println("B.run() called.");
if (!running){
System.err.println("B: calling this.cancel().");
this.cancel();
return;
}
}
public boolean cancel(){
System.err.println("Canceling TaskB");
return super.cancel();
}
}
private void start(){
this.running = true; // Flag to indicate if the server loop should continue running or not
final java.util.Timer timerA = new java.util.Timer();
final TaskA taskA = new TaskA();
timerA.schedule(taskA, 0, 400);
final java.util.Timer timerB = new java.util.Timer();
final TaskB taskB = new TaskB();
timerB.schedule(taskB, 0, 500);
class StopperTask extends java.util.TimerTask {
private java.util.Timer myTimer;
StopperTask(java.util.Timer timer){
myTimer = timer;
}
public void run(){
taskA.cancel();
taskB.cancel();
timerA.cancel();
timerB.cancel();
this.cancel();
myTimer.cancel();
System.err.println("Stopper task completed");
}
}
final java.util.Timer stopperTimer = new java.util.Timer();
final StopperTask stopperTask = new StopperTask(stopperTimer);
stopperTimer.schedule(stopperTask, 2*1000);
/** Register witjh JVM to be notified on when the JVM is about to exit */
java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("shutting down...");
running = false;
taskA.cancel();
taskB.cancel();
timerA.cancel();
timerB.cancel();
stopperTask.cancel();
stopperTimer.cancel();
System.err.println("All tasks and timers canceled, exiting");
System.exit(0);
}
});
}
public static void main(String[] args) {
new TimerTest().start();
}
private boolean running = false;
}
只是一个好奇的评论,你为什么不导入所有的类,而是用全名引用它们?你显然有进口的能力。 – skiwi
“一切都按预期进行,但程序只是在Stopper任务执行时挂起”,这句话令人困惑。阻止者任务总是在某个时间点发出(或)? – kosa
添加条件以测试进程是否正在运行,然后取消它。查看它是否挂起。 – Phani