zoukankan      html  css  js  c++  java
  • 高并发场景下System.currentTimeMillis()的性能优化

    一、前言

    System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我也不知道,不过听说在100倍左右),然而该方法又是一个常用方法,

    有时不得不使用,比如生成wokerId、打印日志什么的,在高并发情形下肯定存在性能问题的,但怎么做才好呢? System.currentTimeMillis()之所以慢是因为

    去跟系统打了一次交道。那什么快?内存!如果该方法从内存直接取数,那不就美滋滋了。

    二、代码实现

    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 SystemClock instance() {
            return InstanceHolder.INSTANCE;
        }
    
        public static long now() {
            return instance().currentTimeMillis();
        }
    
        public static String nowDate() {
            return new Timestamp(instance().currentTimeMillis()).toString();
        }
    
        private void scheduleClockUpdating() {
    
            ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
    
                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = new Thread(r, "System Clock");
                    thread.setDaemon(true);
                    return thread;
                }
            });
    
            scheduler.scheduleAtFixedRate(new Runnable() {
    
                @Override
                public void run() {
                    now.set(System.currentTimeMillis());
                }
            }, period, period, TimeUnit.MILLISECONDS);
        }
    
        private long currentTimeMillis() {
            return now.get();
        }
    
        private static class InstanceHolder {
            public static final SystemClock INSTANCE = new SystemClock(1);
        }
    }

    用的时候直接调用SystemClock.now();就ok了。

    测试

    写了一个简单的测试代码:

        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            for (long i = 0; i < Integer.MAX_VALUE; i++) {
                SystemClock.now();
            }
            long end = System.currentTimeMillis();
            System.out.println("SystemClock Time:" + (end - start) + "毫秒");
            long start2 = System.currentTimeMillis();
            for (long i = 0; i < Integer.MAX_VALUE; i++) {
                System.currentTimeMillis();
            }
            long end2 = System.currentTimeMillis();
            System.out.println("currentTimeMillis Time:" + (end2 - start2) + "毫秒");
        }

    输出结果是:
      SystemClock Time:1787毫秒
      currentTimeMillis Time:33851毫秒
      看着结果效率提升还是挺明显的。

      所有的进步都是不稳定, 一个问题解决了又不得不面对一个新的问题。
     
    转载自:https://www.cnblogs.com/nyvi/p/8837012.html
  • 相关阅读:
    爬虫工具包
    用于模型选择的AIC与BIC
    4.数据结构---堆
    海量数据查询
    机器学习---算法汇总目录
    RNN/LSTM/GRU/seq2seq公式推导
    Dropout正则化和其他方法减少神经网络中的过拟合
    查看动态链接库中函数参数类型
    ANSI、ASCII、GB2312、GBK
    Unicode(UTF-8, UTF-16)令人混淆的概念
  • 原文地址:https://www.cnblogs.com/junjiang3/p/9195074.html
Copyright © 2011-2022 走看看