SystemClock.java 2.77 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
/**
* Copyright (c) 2011-2020, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.baomidou.mybatisplus.toolkit;

import java.sql.Timestamp;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
* <p>
* 高并发场景下System.currentTimeMillis()的性能问题的优化
* </p>
* <p>
* System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右)<br>
* System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道<br>
* 后台定时更新时钟,JVM退出时,线程自动回收<br>
* 10亿:43410,206,210.72815533980582%<br>
* 1亿:4699,29,162.0344827586207%<br>
* 1000万:480,12,40.0%<br>
* 100万:50,10,5.0%<br>
* </p>
*
* @author hubin
* @Date 2016-08-01
*/
public class SystemClock {

private final long period;
private final AtomicLong now;

private SystemClock(long period) {
this.period = period;
this.now = new AtomicLong(System.currentTimeMillis());
scheduleClockUpdating();
}

private static class InstanceHolder {
public static final SystemClock INSTANCE = new SystemClock(1);
}

private static SystemClock instance() {
return InstanceHolder.INSTANCE;
}

private void scheduleClockUpdating() {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, "System Clock");
thread.setDaemon(true);
return thread;
}
});
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
now.set(System.currentTimeMillis());
}
}, period, period, TimeUnit.MILLISECONDS);
}

private long currentTimeMillis() {
return now.get();
}

public static long now() {
return instance().currentTimeMillis();
}
public static String nowDate() {
return new Timestamp(instance().currentTimeMillis()).toString();
}

}