系统高并发直接调用System.currentTimeMillis()存在性能问题,因此统一个后台线程维护当前时间缓存。
import org.jetbrains.annotations.NotNull;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* <p> 获取当前时间时钟时钟工具类 解决直接获取时间的性能问题 </p>
*
* @author mori
* @since 2020/12/30 11:53
*/
public final class SystemClock {
private final long period;
private final AtomicLong now;
private SystemClock(long period) {
this.period = period;
this.now = new AtomicLong(System.currentTimeMillis());
this.scheduleClockUpdating();
}
private static SystemClock instance() {
return InstanceHolder.INSTANCE;
}
public static long now() {
return instance().currentTimeMillis();
}
public static String nowDate() {
return (new Timestamp(instance().currentTimeMillis())).toString();
}
/**
* 现在当地的日期时间
*
* @return {@link LocalDateTime}
*/
public static LocalDateTime nowLocalDateTime() {
Instant instant = Instant.ofEpochMilli(instance().currentTimeMillis());
ZoneId zone = ZoneId.systemDefault();
return LocalDateTime.ofInstant(instant, zone);
}
private void scheduleClockUpdating() {
new ScheduledThreadPoolExecutor(1, new UpdateThreadDaemonFactory()
).scheduleAtFixedRate(() -> {
now.set(System.currentTimeMillis());
}, this.period, this.period, TimeUnit.MILLISECONDS);
}
private long currentTimeMillis() {
return this.now.get();
}
public static class UpdateThreadDaemonFactory implements ThreadFactory {
private static int threadInitNumber = 0;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
@Override
public Thread newThread(@NotNull Runnable r) {
Thread thread = new Thread(r, "Thread-System-Lock-" + nextThreadNum());
thread.setDaemon(true);
return thread;
}
}
private static class InstanceHolder {
private static final SystemClock INSTANCE = new SystemClock(1L);
private InstanceHolder() {
}
}
}