高并发场景下System.currentTimeMillis()的性能问题的优化
1 package cn.ucaner.alpaca.common.util.key; 2 3 import java.sql.Timestamp; 4 import java.util.concurrent.*; 5 import java.util.concurrent.atomic.AtomicLong; 6 7 /** 8 * 高并发场景下System.currentTimeMillis()的性能问题的优化 9 * <p><p> 10 * System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右)<p> 11 * System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道<p> 12 * 后台定时更新时钟,JVM退出时,线程自动回收<p> 13 * 10亿:43410,206,210.72815533980582%<p> 14 * 1亿:4699,29,162.0344827586207%<p> 15 * 1000万:480,12,40.0%<p> 16 * 100万:50,10,5.0%<p> 17 * @author lry 18 */ 19 public class SystemClock { 20 21 private final long period; 22 23 private final AtomicLong now; 24 25 ExecutorService executor = Executors.newSingleThreadExecutor(); 26 27 private SystemClock(long period) { 28 this.period = period; 29 this.now = new AtomicLong(System.currentTimeMillis()); 30 scheduleClockUpdating(); 31 } 32 33 private static class InstanceHolder { 34 public static final SystemClock INSTANCE = new SystemClock(1); 35 } 36 37 private static SystemClock instance() { 38 return InstanceHolder.INSTANCE; 39 } 40 41 private void scheduleClockUpdating() { 42 ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { 43 @Override 44 public Thread newThread(Runnable runnable) { 45 Thread thread = new Thread(runnable, "System Clock"); 46 thread.setDaemon(true); 47 return thread; 48 } 49 }); 50 scheduler.scheduleAtFixedRate(new Runnable() { 51 @Override 52 public void run() { 53 now.set(System.currentTimeMillis()); 54 } 55 }, period, period, TimeUnit.MILLISECONDS); 56 } 57 58 private long currentTimeMillis() { 59 return now.get(); 60 } 61 62 public static long now() { 63 return instance().currentTimeMillis(); 64 } 65 66 public static String nowDate() { 67 return new Timestamp(instance().currentTimeMillis()).toString(); 68 } 69 70 /** 71 * @Description: Just for test 72 * @param args void 73 * @throws InterruptedException 74 * @Autor: Jason - jasonandy@hotmail.com 75 */ 76 public static void main(String[] args) throws InterruptedException { 77 for (int i = 0; i < 100; i++) { 78 System.out.println(nowDate()); 79 Thread.sleep(1000); 80 } 81 } 82 } 83 //Outputs 84 //2018-05-10 15:37:18.774 85 //2018-05-10 15:37:19.784 86 //2018-05-10 15:37:20.784 87 //2018-05-10 15:37:21.785 88 //2018-05-10 15:37:22.784 89 //2018-05-10 15:37:23.784 90 //2018-05-10 15:37:24.785 91 //2018-05-10 15:37:25.784 92 //2018-05-10 15:37:26.785 93 //2018-05-10 15:37:27.786 94 //2018-05-10 15:37:28.785 95 //2018-05-10 15:37:29.785 96 //2018-05-10 15:37:30.785 97 //2018-05-10 15:37:31.785