java - 如何安排任务运行一次?

标签 java scheduled-tasks scheduledexecutorservice

我想延迟做某事,就像设置一个倒计时器一样,在一定时间后“做一件事”。

我希望程序的其余部分在等待时继续运行,因此我尝试创建自己的线程,其中包含一分钟的延迟:

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


虽然这或多或少有效,但似乎应该有更好的方法来做到这一点。

经过一番搜索,我发现了很多这样的问题,但它们并没有真正解决我想要做的事情:

我不需要这么复杂的东西;我只想在一段时间后做一件事,同时让程序的其余部分仍然运行。

我应该如何安排一次性任务来“做一件事”?

最佳答案

java.util.Timer 曾经是安排 future 任务的好方法,现在最好1改为使用 java.util.concurrent 中的类。包。

有一个 ScheduledExecutorService 专门设计用于在延迟后运行命令(或定期执行它们,但这与这个问题无关)。

它有一个 schedule(Runnable, long, TimeUnit) 方法

Creates and executes a one-shot action that becomes enabled after the given delay.


使用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();
    }
}

通过这种方式获得的好处之一是 ScheduledFuture<?>调用 schedule() 返回的对象.

这可以让你摆脱额外的 boolean变量,直接检查作业是否运行即可。

如果您不想再等待,也可以通过调用 cancel() 来取消计划任务。方法。


1参见Java Timer vs ExecutorService?出于避免使用 Timer 的原因支持ExecutorService .

关于java - 如何安排任务运行一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59549771/

相关文章:

java - 附加日期时间并将其传递给创建文件

java - Jzy3d/JOGL 的 OSGi 路径错误(未找到 gluegen-rt)

mysql - Java调度线程杀死数据库

java - 从ScheduledExecutorService示例用法获取编译错误

java - 类似于基本 Java 中的 FileCopyUtils.copy 方法

Java - 从流数据包中保存 RTSP 快照

mysql - 在确定的时间安排查询执行

ruby-on-rails - 使用 Clockwork 的计划作业和自定义时钟进程

c# - 从 Web 应用程序运行计划任务

java - Java ScheduledExecutorService 和 Quartz Scheduler 之间哪个最好使用?