Java 如何安排任务运行一次?

Java 如何安排任务运行一次?,java,scheduled-tasks,scheduledexecutorservice,Java,Scheduled Tasks,Scheduledexecutorservice,我想延迟做一些事情,比如设置一个倒计时,在一定时间后“做一件事” 我希望程序的其余部分在等待时保持运行,因此我尝试创建自己的线程,其中包含一分钟的延迟: public class Scratch { private static boolean outOfTime = false; public static void main(String[] args) { Thread countdown = new Thread() { @Ove

我想延迟做一些事情,比如设置一个倒计时,在一定时间后“做一件事”

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

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

虽然这或多或少起到了作用,但似乎应该有更好的方法来做到这一点

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

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

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

虽然过去是安排未来任务的好方法,但现在更倾向于1使用
java.util.concurrent
包中的类

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

它有一种方法

创建并执行在给定延迟后启用的一次性操作


使用
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();
    }
}
import java.util.concurrent.*;
公共课刮刮{
私有静态最终ScheduledExecutorService调度器=Executors.newScheduledThreadPool(1);
公共静态void main(字符串[]args){
System.out.println(“现在开始倒计时一分钟…”);
ScheduledFuture倒计时=scheduler.schedule(new Runnable()){
@凌驾
公开募捐{
//做那件事
System.out.println(“超时!”);
}},1,时间单位(分钟);
而(!countdown.isDone()){
试一试{
睡眠(1000);
System.out.println(“在这里做其他事情”);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
scheduler.shutdown();
}
}
通过这样做,您可以得到的一个好处是调用
ScheduledFuture()
返回的
ScheduledFuture
对象

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

如果不想再等待,也可以通过调用其方法取消计划任务



1请查看避免使用
计时器的原因,以便使用
执行器服务

谢谢它对我有用。我使用scheduler按运行时计算的批处理间隔安排任务

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

此计划执行器将运行一次或每分钟一次。我希望我的操作只运行一次并退出。@qualebs在本例中,操作只运行一次。传递到
schedule()
方法中的时间是运行操作之前的延迟。@azurefrog是的,它只运行一次,我希望
倒计时
对象从这里提供的
时间单位
中获得1分钟的值。如何将此代码修改为每1分钟连续运行一次?我的意思是,与您现在的代码行为正好相反,为什么不使用CountDownLatch替换ScheduleService实现的CountDown对象?