java 使程序运行 5 分钟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16444982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:58:32  来源:igfitidea点击:

Making a program run for 5 minutes

javatimertimertask

提问by Shaun

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

所以我想用 Timer 和 TimerTask 类尝试一些东西。

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.

我能够在 30 秒后得到一行代码来执行。我现在一直在尝试做的是让这行代码执行 5 分钟。

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.

我在 for 循环中使用数字 10 来查看 timer.schedule 在循环的下一次迭代期间是否会再等待 30 秒。

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.

知道我应该怎么做吗?我尝试使用 schedule 方法并传入一个参数 for period,但这只会让它重新执行并且它从未停止过。

回答by Vishal K

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

Java 在java.util.concurrent包中提供了一组丰富的 API来完成这些任务。这些 API 之一是ScheduledExecutorService. 例如,考虑下面给出的代码:此代码将在每秒钟后执行长达数分钟:Runnabletask305

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

回答by killscreen

The issue you're running into is that the scheduled Timerruns on a different thread - that is, the next iteration of your forloop 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.

您遇到的问题是计划Timer在不同的线程上运行 - 也就是说,for循环的下一次迭代在计划后立即开始运行,而不是 30 秒后。看起来您的代码同时启动了 10 个计时器,这意味着它们应该在(大约)30 秒后一次性全部打印出来。

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, Timerdoeshave a cancelmethod to prevent subsequent executions.

当您尝试使用schedule(带有第三个参数)的重复版本时,您走在正确的轨道上。正如您所指出的,这不是您想要的,因为它无限期地运行。但是,Timer确实cancel防止后续执行的方法。

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

回答by Bj?rn Br?then

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.

我不知道这个解决方案是否有垃圾收集器的问题,但我还是把它扔在这里。也许有人清除了这一点,我也学到了一些东西。基本上,如果有剩余时间,计时器会设置一个新计时器,并且应该在 5 分钟后停止。

Main.java:

主.java:

public class Main {
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer(300000,30000);
        myTimer.startTimer();
    }
}

MyTimer.java:

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

回答by Mena

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 exactly5 minutes - see documentation for TimerTask.

另请注意,该应用程序可能不会恰好运行5 分钟 - 请参阅 TimerTask 的文档。

回答by Supericy

Your solution is pretty close to working, you just have to multiply the delay by the counter (in your case, i):

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