Using while(true) and TimeUnit.SECONDS.sleep is a possibility, but it is bad practice (as you can see from the sheer number of downvotes on this post). This SO answer gives some reasons as to why:
- low level, subject to spurious wakeups
- clock drift
- control
- intent of code
there are others.
The basic way to achieve this is to use a java.util.Timer, not to be confused with a javax.swing.Timer:
final Timer timer = new Timer("MyTimer");
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, TimeUnit.SECONDS.toMillis(1));
You need to call timer.cancel() to stop the timer - as the timer is running a non-daemon thread your program will not exit until that is done.
A more advanced way, which allows multiple tasks to be scheduled to run at different intervals on a pool of the ScheduledExecutorService. This allows you to scheduleAtFixedRate which runs a task every second (regardless of how long it takes to run, i.e. the gap between start times is always the same) or scheduleWithFixedDelay which runs a task at one second intervals (i.e. the gap between the end of one run and the start of the next is always the same).
For example:
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final ScheduledFuture<?> handle = executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(System.currentTimeMillis());
}
}, 0, 1, TimeUnit.SECONDS);
To cancel the particular task you would call handle.cancel(false) (as interrupting has no effect) and to stop the executorService you would call executorService.shutdown() after which you might want to add a executorService.awaitTermination(1, TimeUnit.DAYS) to wait for all the tasks to finish.
EDIT
A comment This can be done more concisely in java 8 with lambda right? (not an expert at lambdas)
The first example, no. A Timer takes a TimerTask, this is an abstract class and not an @FunctionalInterface so a lambda is not possible. In the second case, sure:
final ScheduledFuture<?> handle = executorService.
scheduleAtFixedRate(() -> System.out.println(System.currentTimeMillis()), 0, 1, TimeUnit.SECONDS);