Making a program run for 5 minutes

前端 未结 5 1971
隐瞒了意图╮
隐瞒了意图╮ 2021-01-26 14:03

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 t

相关标签:
5条回答
  • 2021-01-26 14:15

    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
    );
    
    0 讨论(0)
  • 2021-01-26 14:17

    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);
        }
    }     
    
    0 讨论(0)
  • 2021-01-26 14:18

    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.

    0 讨论(0)
  • 2021-01-26 14:18

    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
        }
    }
    
    0 讨论(0)
  • 2021-01-26 14:25

    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.");
        }
    }
    
    0 讨论(0)
提交回复
热议问题