Как запланировать выполнение задачи один раз?
Я хочу отложить что-то делать, по линии установки таймера обратного отсчета, который будет "делать что-то" через определенное количество времени.
Я хочу, чтобы остальная часть моей программы продолжала работать, пока я жду, поэтому я попытался сделать свой собственный 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();
}
}
}
}
Хотя это сработало, более или менее, казалось, что должен быть лучший способ сделать это.
после некоторого поиска я нашел кучу вопросов, подобных этим но на самом деле они не касаются того, что я пытаюсь сделать:
- как запланировать выполнение задачи с периодическими интервалами?
- как я могу запускать свою TimerTask каждый день 2 PM
- как запускать определенную задачу каждый день в определенное время с помощью ScheduledExecutorService?
- Java выполняет задачу с несколькими попытками и таймаутом
мне ничего не нужно это сложно; я просто хочу сделать одну вещь через определенное количество времени, позволяя остальной части программы все еще работать.
Как я должен планировать одноразовую задачу ,чтобы"сделать что-то"?
1 ответов
С 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 против ExecutorService? по причинам, чтобы избежать использования Timer
в пользу ExecutorService
.