如何安排一个任务只运行一次?

54 浏览
0 Comments

如何安排一个任务只运行一次?

我想延迟执行某项任务,类似于设置一个倒计时器,在一定时间后执行“某事”。

我希望在等待期间保持程序的运行,所以我尝试创建一个包含一分钟延迟的自定义线程:

public class Scratch {
    private static boolean outOfTime = false;
    public static void main(String[] args) {
        Thread countdown = new Thread() {
            @Override
            public void run() {
                try {
                    // 等待一段时间
                    System.out.println("现在开始一分钟倒计时...");
                    Thread.sleep(60 * 1000);
                    // 执行某事
                    outOfTime = true;
                    System.out.println("时间到了!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        countdown.start();
        while (!outOfTime) {
            try {
                Thread.sleep(1000);
                System.out.println("在这里做其他事情");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

虽然这种方法基本上能够工作,但似乎应该有更好的方法来实现这个目标。

经过一些搜索,我发现了一些类似的问题,但它们并没有解决我想要做的事情:

- [如何按周期间隔安排任务运行?](https://stackoverflow.com/questions/4544197/how-do-i-schedule-a-task-to-run-at-periodic-intervals)

- [如何每天下午2点运行我的TimerTask?](https://stackoverflow.com/questions/9375882/how-i-can-run-my-timertask-everyday-2-pm)

- [如何使用ScheduledExecutorService在特定时间每天运行某个任务?](https://stackoverflow.com/questions/20387881/how-to-run-certain-task-every-day-at-a-particular-time-using-scheduledexecutorse)

- [Java如何执行带有重试次数和超时的任务?](https://stackoverflow.com/questions/11751329/java-execute-task-with-a-number-of-retries-and-a-timeout)

我不需要这么复杂的东西;我只想在一定时间后执行一次任务,同时让程序的其他部分继续运行。

我应该如何安排一次性任务来执行“某事”?

0
0 Comments

问题出现的原因是需要在特定的时间点运行一次任务。解决方法是使用调度器和计算得到的时间间隔来安排任务的执行。

具体的解决方法如下所示:

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

以上是解决该问题的代码。

0
0 Comments

如何安排一个任务只运行一次?

在过去,java.util.Timer是一种在未来安排任务的好方法,但现在更倾向于使用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() {
            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();
    }
}

通过这种方式,您可以获得从调用schedule()返回的ScheduledFuture<?>对象。

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

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

这种方法的一个好处是您可以使用CountDownLatch来替换ScheduleService实现的倒计时对象。

在这个例子中,动作只会运行一次。传递给schedule()方法的时间是动作运行之前的延迟时间。

如果要持续每1分钟运行此代码,可以如何修改?我的意思是改变代码的行为,与现在相反。

为什么不使用CountDownLatch来替换ScheduleService实现的倒计时对象?

0