Making a program run for 5 minutes

你。 提交于 2019-12-02 14:44:54

问题


So I wanted to try out something for a bit with the Timer and TimerTask classes.

I was able to get a line of code to execute after 30 seconds elapsed. What I've been trying to do now is to get this line of code to execute for 5 minuets.

This is what I originally tried

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
        );
    }   
}

I used the number 10 in the for loop to see if the timer.schedule would wait for another 30 seconds during the next iteration of the loop.

Any idea how I should go about this? I tried using the schedule method with a parameter passed in for period, but that only made it re-execute and it never stopped.


回答1:


The issue you're running into is that the scheduled Timer runs on a different thread - that is, the next iteration of your for loop starts running immediately after scheduling, not 30 seconds later. It looks like your code starts ten timers all at once, which means they should all print (roughly) 30 seconds later, all at once.

You were on the right track when you tried using the recurring version of schedule (with the third parameter). As you noted, this isn't quite what you want because it runs indefinitely. However, Timer does have a cancel method to prevent subsequent executions.

So, you should try something like:

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:


Java has provided a rich set of APIs in java.util.concurrent package to achieve such tasks. One of these APIs is ScheduledExecutorService. For example consider the code given below: This code will execute the Runnable task after every 30 seconds for upto 5 minutes:

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);
    }
}     



回答3:


here's a workaround I'm ashamed of presenting:

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
        );  
    }
}

Also please note that the application might not run exactly 5 minutes - see documentation for TimerTask.




回答4:


Your solution is pretty close to working, you just have to multiply the delay by the counter (in your case, 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:


I don't know if this solution has problems with the garbage collector or not, but I throw it in here anyways. Maybe someone clears that out, and I learn something as well. Basically a timer sets a new timer if there is time left, and it should stop after 5 minutes.

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


来源:https://stackoverflow.com/questions/16444982/making-a-program-run-for-5-minutes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!