zoukankan      html  css  js  c++  java
  • System.currentTimeMillis() 优化

      在优化一个IOT项目,一个老爷级代码了,具体有多少人员参与了编码我也记不清了。某日随手查询了下 System.currentTimeMillis() 调用的代码,不看不知道,一看~嚯 

    700多处 System.currentTimeMillis() 就躺在那里。就我所知的,当设备有数据上传时,程序为了给这条数据一个deviceID,可是用了时间戳+随机字符的方式的。那并发量可是海了去了。掐指一算,如果:tps = 2000,那每秒就调用了2000次 System.currentTimeMillis(),如果把这两千次压缩成1次,是不是效率就有提高了呢?

    写一段测试代码:逻辑为:

    首次调用 系统时间,返回当前系统时间,

    同时创建一个异步线程,该线程每秒运行一次,每次间隔1秒,每次都获取一下系统时间,并把时间戳赋值到内存变量。

    后期如有调用系统时间,直接获取内存变量。

    优点是:对于高并发情况的系统时间获取,提高了系统时间获取效率。

    代码:

    package com.example.currentTimeMillis;
    
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicLong;
    
    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;
        }
        
        private static class InstanceHolder {
            public static final SystemClock INSTANCE = new SystemClock(1); 
        }
        
        public static long now() {
            return instance().currentTimeMillis();    
        }
        
        private long currentTimeMillis() {
            return now.get();  
        }
        
        private void scheduleClockUpdating() {
            // 首次调用,创建线程
            ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1,  r -> {
                Thread thread = new Thread(r, "System Clock");
                thread.setDaemon(true);
                return thread;
            } );
            // 首次调用后,线程每秒获取一次系统时间,并赋值给 AtomicLong now;
            scheduler.scheduleAtFixedRate( () -> now.set(System.currentTimeMillis()) , period, period, TimeUnit.MILLISECONDS );
        }
        
        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            System.out.println("循环获取时间次数:"+Integer.MAX_VALUE);
            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) + "毫秒");
            
        }
        
    }

    运行结果:

    运行效果明显不同呀 ~ 

    整理好测试代码,并嵌入到代码中。

  • 相关阅读:
    采用[ICONIX] 方法实践BLOG设计之一 [问题域建模]
    关于“三国众谋士”之IT从业可行性报告
    采用[ICONIX] 方法实践BLOG设计之二 [用例建模]
    NET框架中的 Decorator 和 Strategy 模式
    域模型向左走(充血),向右走(贫血)
    采用[ICONIX] 方法实践BLOG设计之五 [初步设计复核]
    Discuz!NT 缓存设计简析 [原创]
    Discuz!NT控件剖析 之 Tab 属性页 [原创: 附源码]
    没有银弹,但可以"扯蛋"
    Discuz!NT控件剖析 之 Button [原创: 附源码]
  • 原文地址:https://www.cnblogs.com/wgy1/p/10813379.html
Copyright © 2011-2022 走看看