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

运行结果:

运行效果明显不同呀 ~ 

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

 

posted @ 2019-05-05 15:38  currentTimeMillis  阅读(314)  评论(0编辑  收藏  举报