如何安排任务运行一次?

时间:2015-12-16 23:26:53

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


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

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

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

我应该如何安排一次性任务到#34;做一件事"?

2 个答案:

答案 0 :(得分:26)

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

通过这种方式做的事情之一就是你从调用ScheduledFuture<?>回来的schedule()对象。

这允许您删除额外的boolean变量,并直接检查作业是否已运行。

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


1 请参阅Java Timer vs ExecutorService?,了解避免使用Timer支持ExecutorService的原因。

答案 1 :(得分:0)

感谢它为我工作。我使用调度程序以在运行时计算的batchinterval调度任务。

    manualTriggerBatchJob.setSchedulingProperties(pblId, batchInterval);
    ScheduledExecutorService scheduledExecutorService =
            Executors.newScheduledThreadPool(5);
    @SuppressWarnings("unchecked")
    ScheduledFuture scheduledFuture =
            scheduledExecutorService.schedule(manualTriggerBatchJob,
            batchIntervalInMin,TimeUnit.MILLISECONDS);