运行 在 Java TimerTask 中连续无延迟地执行任务
Run a task continuously without delay inside a Java TimerTask
我如何 运行 TimerTask 中的一组特定指令连续无延迟地持续一段时间?以下是我试图实现上述代码的代码。
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Test started at: " + new Date());
// Do something continuously without delay
System.out.println("Test finished at: " + new Date());
}
}, 0);
schedule
方法的第二个参数是开始定时器任务的时间(或相对于现在的延迟),而不是定时器将执行的时间长度。
从你的问题中还不完全清楚,但我假设你希望任务在未来的特定时间(或相对于现在的延迟)开始和停止。如果是这样,我的方法是创建一个 Thread
来完成您需要的任务。由于 TimerTask
是一个 Runnable
,一旦 Timer
启动它就作为 Thread
执行,您可以只使用 TimerTask
的一个实例。确保 Runnable
包含一个可设置的字段,如 running
。在那个线程中,运行 你在 while 循环中的任务是这样的:
public void run() {
while(running) { /* do my task */ }
}
然后,使用一个 Timer
安排 Runnable
在您需要的时间开始。使用另一个计时器在您希望它停止时将同一线程的 running
参数设置为 false。 running
参数应该是可变的,以确保第一个计时器线程立即看到第二个计时器线程对其所做的更改。所以它看起来像这样(未测试):
class StoppableTimerTask extends TimerTask {
private volatile boolean running = true;
public void stopRunning() { this.running = false; }
public void run() {
while(running) { /* do my task */ }
}
}
final StoppableTimerTask task = new StoppableTimerTask();
timer.schedule(task, startTime);
timer.schedule(new TimerTask() {
public void run() {
task.stopRunning();
}
}, stopTime);
根据您的 "something" 是什么,您可能还想查看线程中断。例如,如果它正在执行阻塞 IO,您的代码将不会循环并检查 running
值,直到阻塞 IO 完成。中断线程(可能)会导致这种情况发生。参见 http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt--。这可能有效也可能无效,并且可能很难正确执行,因此如果您需要此线程尽可能接近所需时间退出,请首选 运行ning 阻塞 I/O 和类似操作更小的超时,以便线程可以更频繁地检查它是否应该继续运行。
UPDATE: 根据注释表明任务应该立即开始,它变得更加简单。初始任务甚至不需要扩展 TimerTask
——它可以只是一个立即启动的常规 Thread
。定时器只需要在指定的未来时间停止它。
我如何 运行 TimerTask 中的一组特定指令连续无延迟地持续一段时间?以下是我试图实现上述代码的代码。
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Test started at: " + new Date());
// Do something continuously without delay
System.out.println("Test finished at: " + new Date());
}
}, 0);
schedule
方法的第二个参数是开始定时器任务的时间(或相对于现在的延迟),而不是定时器将执行的时间长度。
从你的问题中还不完全清楚,但我假设你希望任务在未来的特定时间(或相对于现在的延迟)开始和停止。如果是这样,我的方法是创建一个 Thread
来完成您需要的任务。由于 TimerTask
是一个 Runnable
,一旦 Timer
启动它就作为 Thread
执行,您可以只使用 TimerTask
的一个实例。确保 Runnable
包含一个可设置的字段,如 running
。在那个线程中,运行 你在 while 循环中的任务是这样的:
public void run() {
while(running) { /* do my task */ }
}
然后,使用一个 Timer
安排 Runnable
在您需要的时间开始。使用另一个计时器在您希望它停止时将同一线程的 running
参数设置为 false。 running
参数应该是可变的,以确保第一个计时器线程立即看到第二个计时器线程对其所做的更改。所以它看起来像这样(未测试):
class StoppableTimerTask extends TimerTask {
private volatile boolean running = true;
public void stopRunning() { this.running = false; }
public void run() {
while(running) { /* do my task */ }
}
}
final StoppableTimerTask task = new StoppableTimerTask();
timer.schedule(task, startTime);
timer.schedule(new TimerTask() {
public void run() {
task.stopRunning();
}
}, stopTime);
根据您的 "something" 是什么,您可能还想查看线程中断。例如,如果它正在执行阻塞 IO,您的代码将不会循环并检查 running
值,直到阻塞 IO 完成。中断线程(可能)会导致这种情况发生。参见 http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt--。这可能有效也可能无效,并且可能很难正确执行,因此如果您需要此线程尽可能接近所需时间退出,请首选 运行ning 阻塞 I/O 和类似操作更小的超时,以便线程可以更频繁地检查它是否应该继续运行。
UPDATE: 根据注释表明任务应该立即开始,它变得更加简单。初始任务甚至不需要扩展 TimerTask
——它可以只是一个立即启动的常规 Thread
。定时器只需要在指定的未来时间停止它。