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
Making a program run for 5 minutes
提问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.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:
Java 在java.util.concurrent
包中提供了一组丰富的 API来完成这些任务。这些 API 之一是ScheduledExecutorService
. 例如,考虑下面给出的代码:此代码将在每秒钟后执行长达数分钟:Runnable
task
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);
}
}
回答by killscreen
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.
您遇到的问题是计划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, Timer
doeshave a cancel
method 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
}
}