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
  • 相关阅读:
    DevExpress ASP.NET v19.1版本亮点:Pivot Grid等控件
    .NET界面控件DevExpress全新发布v19.1.5|改进Office 2019主题
    Kendo UI for jQuery使用教程:操作系统/jQuery支持等
    Web安全篇之SQL注入攻击
    SQL Server中timestamp(时间戳)和rowversion(版本戳)
    PyCharm2019 激活码
    性能测试 vs 负载测试 vs 压力测试
    一套完整的压力测试项目文档
    Visual Studio性能计数器,负载测试结果分析- Part III
    Visual Studio进行负载测试,RIG和负载测试术语- Part II
  • 原文地址:https://www.cnblogs.com/junjiang3/p/9195074.html
Copyright © 2011-2022 走看看