After contemplating this for a while I do agree that Thread.sleep is the straight forward way to stall the main thread in a loop obviously.
In other use cases that may be differnt, though, since, well, it stalls a thread that could do something else in the meantime. Here you have a discussion of Timer vs Thread.sleep, if you're interested and here another somewhat less comprehensive answers for a question that could pass as a duplicate.
public static void sleep(int someDelay) {
try {
Thread.sleep(someDelay);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
For more demanding scenarios ScheduledThreadPoolExecutor
is your friend.
ScheduledExecutorService executor = Executors.newScheduledThreadPool(poolSize);
executor.schedule(() -> {
// doSmthg
}, 12, TimeUnit.HOURS);
Another way to go was Timer/Timertask, which is now usually discouraged (thx to @rkosegi for pointing this out) in favor of ScheduledThreadPoolExecutor. A poolsize of 1 mimicks Timer/Timertask functionality.
On the other hand Timer/Timertask has the upper hand for large numbers of small tasks in a single thread scenario "Implementation note: This class scales to large numbers of concurrently scheduled tasks (thousands should present no problem). Internally, it uses a binary heap to represent its task queue, so the cost to schedule a task is O(log n), where n is the number of concurrently scheduled tasks.", where ScheduledExecutorService uses a BlockingQueue.
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// do smthg;
}
}, someDelay);