azu*_*rog 22 java scheduled-tasks scheduledexecutorservice
我想延迟做一些事情,就像设置倒计时器一样,在一段时间后"做一件事".
我希望我的其余程序在我等待的时候继续运行,所以我尝试自己Thread创建一个包含一分钟延迟的程序:
public class Scratch {
private static boolean outOfTime = false;
public static void main(String[] args) {
Thread countdown = new Thread() {
@Override
public void run() {
try {
// wait a while
System.out.println("Starting one-minute countdown now...");
Thread.sleep(60 * 1000);
// do the thing
outOfTime = true;
System.out.println("Out of time!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
countdown.start();
while (!outOfTime) {
try {
Thread.sleep(1000);
System.out.println("do other stuff here");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这或多或少有效,但似乎应该有更好的方法来做到这一点.
经过一番搜索,我发现了一堆像这样的问题,但它们并没有真正解决我想要做的事情:
我不需要这么复杂的东西; 我只想在一段时间后做一件事,同时让程序的其余部分仍然运行.
我该如何安排一次性任务来"做事"?
azu*_*rog 27
虽然java.util.Timer曾经是安排今后的任务的好方法,现在是最好1改为使用类的java.util.concurrent包.
有一个ScheduledExecutorService专门设计用于在延迟后运行命令(或定期执行它们,但这与此问题无关).
它有一个schedule(Runnable, long, TimeUnit)方法
创建并执行在给定延迟后启用的一次性操作.
使用ScheduledExecutorService你可以像这样重写你的程序:
import java.util.concurrent.*;
public class Scratch {
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
System.out.println("Starting one-minute countdown now...");
ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {
@Override
public void run() {
// do the thing
System.out.println("Out of time!");
}}, 1, TimeUnit.MINUTES);
while (!countdown.isDone()) {
try {
Thread.sleep(1000);
System.out.println("do other stuff here");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
scheduler.shutdown();
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式做事所带来的好处之一就是ScheduledFuture<?>你从召唤中回来的对象schedule().
这允许您摆脱额外的boolean变量,并直接检查作业是否已运行.
如果您不想再通过调用其cancel()方法等待,也可以取消计划任务.
1请参阅Java Timer vs ExecutorService?为避免使用Timer赞成的原因ExecutorService.
| 归档时间: |
|
| 查看次数: |
24579 次 |
| 最近记录: |