让程序运行5分钟



所以我想尝试一下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来查看计时器是否。Schedule将在循环的下一次迭代中再等待30秒。

你知道我该怎么做吗?我尝试使用schedule方法,传入一个参数,但这只会使它重新执行,它永远不会停止。

Java在java.util.concurrent包中提供了一组丰富的api来实现这些任务。其中一个api是ScheduledExecutorService。例如,考虑下面给出的代码:这段代码将在每30秒后执行Runnable task,持续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);
    }
}     

您遇到的问题是调度的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
);

这是一个我羞于展示的变通方法:

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文档。

您的解决方案非常接近工作,您只需将延迟乘以计数器(在您的情况下为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
    }
}

我不知道这个解决方案是否与垃圾收集器有问题,但我还是把它扔在这里。也许有人把它清除了,我也学到了一些东西。基本上定时器设置一个新的定时器,如果还有时间,它应该在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.");
    }
}

相关内容

  • 没有找到相关文章

最新更新