所以我想用Timer和TimerTask类来尝试一些东西。
我能够在30秒后获得一行代码。 我现在要做的就是让这行代码执行5分钟。
这是我最初的尝试
public static void main(String[] args)
{
for ( int i = 0; i <= 10; i ++ )
{
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000
);
}
}
我在for循环中使用数字10来查看timer.schedule是否会在循环的下一次迭代期间等待另外30秒。
知道我应该怎么做吗?我尝试将schedule方法与传入的参数一起使用,但只是让它重新执行并且从未停止过。
答案 0 :(得分:2)
Java在java.util.concurrent
包中提供了一组丰富的API来实现这些任务。其中一个API是ScheduledExecutorService
。例如,请考虑下面给出的代码:此代码将在task
秒之后执行Runnable
30
,最多5
分钟:
import java.util.concurrent.*;
class Scheduler
{
private final ScheduledExecutorService service;
private final long period = 30;//Repeat interval
public Scheduler()
{
service = Executors.newScheduledThreadPool(1);
}
public void startScheduler(Runnable runnable)
{
final ScheduledFuture<?> handler = service.scheduleAtFixedRate(runnable,0,period,TimeUnit.SECONDS);//Will cause the task to execute after every 30 seconds
Runnable cancel = new Runnable()
{
@Override
public void run()
{
handler.cancel(true);
System.out.println("5 minutes over...Task is cancelled : "+handler.isCancelled());
}
};
service.schedule(cancel,5,TimeUnit.MINUTES);//Cancels the task after 5 minutes
}
public static void main(String st[])
{
Runnable task = new Runnable()//The task that you want to run
{
@Override
public void run()
{
System.out.println("I am a task");
}
};
Scheduler sc = new Scheduler();
sc.startScheduler(task);
}
}
答案 1 :(得分:1)
您遇到的问题是预定的Timer
在不同的线程上运行 - 也就是说,for
循环的下一次迭代在调度后立即开始运行,而不是30秒后。看起来你的代码会同时启动十个计时器,这意味着它们应该在30秒后全部打印,一次全部打印。
当您尝试使用schedule
的重复版本(第三个参数)时,您处于正确的轨道上。如你所知,这不是你想要的,因为它无限期地运行。但是,Timer
确实采用cancel
方法来阻止后续执行。
所以,你应该尝试类似的东西:
final Timer timer = new Timer();
// Note that timer has been declared final, to allow use in anon. class below
timer.schedule( new TimerTask()
{
private int i = 10;
public void run()
{
System.out.println("30 Seconds Later");
if (--i < 1) timer.cancel(); // Count down ten times, then cancel
}
}, 30000, 30000 //Note the second argument for repetition
);
答案 2 :(得分:0)
这是一个解决方法,我很惭愧地提出:
package test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class FiveMinutes {
private static int count = 0;
// main method just to add example
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Count is: " + count);
if (count == 1) {
System.err.println("... quitting");
System.exit(0);
}
count++;
}
},
// starting now
new Date(),
// 5 minutes
300000l
);
}
}
另请注意,应用程序可能无法完全运行5分钟 - 请参阅TimerTask的文档。
答案 3 :(得分:0)
你的解决方案非常接近工作,你只需要将延迟乘以计数器(在你的情况下为i
):
public static void main(String[] args)
{
for (int i = 1; i <= 10; i++) // start i at 1 for initial delay
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000 * i); // 5 second intervals
}
}
答案 4 :(得分:0)
我不知道这个解决方案是否与垃圾收集器有问题,但我还是把它扔进去了。也许有人清除了这一点,我也学到了一些东西。基本上,如果有剩余时间,计时器会设置一个新的计时器,它应该在5分钟后停止。
<强> Main.java:强>
public class Main {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer(300000,30000);
myTimer.startTimer();
}
}
<强> MyTimer.java:强>
import java.util.Timer;
import java.util.TimerTask;
public class MyTimer {
private int totalRunningTime;
private int currentTime = 0;
private int intervalTime;
private Timer timer = new Timer();
public MyTimer(int totalRunningTime, int intervalTime) {
this.totalRunningTime = totalRunningTime;
this.intervalTime = intervalTime;
}
public void startTimer() {
startTimer(intervalTime);
}
private void startTimer(int time) {
timer.schedule(new TimerTask() {
public void run() {
if (currentTime <= totalRunningTime - intervalTime) {
printTimeSinceLast(intervalTime / 1000);
currentTime += intervalTime;
startTimer(intervalTime);
} else if (currentTime < totalRunningTime) {
int newRestIntervalTime = totalRunningTime - currentTime;
printTimeSinceLast(newRestIntervalTime / 1000);
currentTime += newRestIntervalTime;
startTimer(newRestIntervalTime);
}
}
}, time);
}
private void printTimeSinceLast(int timeSinceLast) {
System.out.println(timeSinceLast + " seconds later.");
}
}