System.currentTimeMillis()
方法的粒度大于1毫秒。如果你重复地调用该方法,在一段时间内你会看到你获取到的都是相同的值,然后突然一下子跳了10/20/30毫秒甚至更多。该方法不是全世界最准确的或者细粒度的计时器。
public class SystemClock {
// 保证其原子性
private final AtomicLong now;
// 时间间隔
private final int period;
private SystemClock(int period) {
this.now = new AtomicLong(System.currentTimeMillis());
this.period = period;
clockUpdate();
}
private static class InstanceHolder {
private static SystemClock INSTANCE = new SystemClock(1);
}
private void clockUpdate() {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r, "SystemClock");
// 主线程退出后,该线程也退出
t.setDaemon(true);
return t;
});
service.scheduleAtFixedRate(() -> now.set(System.currentTimeMillis()), period, period, TimeUnit.MILLISECONDS);
}
public static long now() {
return InstanceHolder.INSTANCE.now.get();
}
}