使程序运行5分钟

时间:2013-05-08 15:49:59

标签: java timer timertask

所以我想用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方法与传入的参数一起使用,但只是让它重新执行并且从未停止过。

5 个答案:

答案 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.");
    }
}