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) + "毫秒");
            
        }
        
    }

    运行结果:

    运行效果明显不同呀 ~ 

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

  • 相关阅读:
    java中的数组长度的计算
    用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。C++实现
    c++中计算数组的长度。以及c++中向量的长度的计算的方式。
    3.mouseenter和mouseover事件的区别
    0.jQuery选择器
    2.点击隐藏盒子
    1.jQuery入口函数
    jquery选项卡效果
    %你考试2020.1
    二十七、rsync同步工具
  • 原文地址:https://www.cnblogs.com/wgy1/p/10813379.html
Copyright © 2011-2022 走看看