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

    前言

    System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我也不知道,不过听说在100倍左右),然而该方法又是一个常用方法,有时不得不使用,比如生成wokerId、打印日志什么的,在高并发情形下肯定存在性能问题的,但怎么做才好呢? System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道。那什么快?内存!如果该方法从内存直接取数,那不就美滋滋了。

    代码实现

    package com.nyvi.support.util;
    
    import java.sql.Timestamp;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.ThreadFactory;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicLong;
    
    /**
     * <p>
     * 高并发场景下System.currentTimeMillis()的性能问题的优化
     * </p>
     * @author czk
     */
    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毫秒
    看着结果效率提升还是挺明显的。

    所有的进步都是不稳定, 一个问题解决了又不得不面对一个新的问题。
  • 相关阅读:
    halcon学习笔记——(5)HDevelop language(异常处理)
    halcon学习笔记——(7)HALCON标定后的二维测量
    halcon学习笔记——(4)HDevelop language(结构语句)
    halcon学习笔记——(3)HDevelop language(基本语句)
    halcon学习笔记——(2)HDevelop language(基本数据类型)
    VMware虚拟机克隆Linux系统后找不到eth0网卡的问题
    完全分布模式安装Hadoop
    Hadoop小程序数据筛选
    SpringMVC访问静态资源
    Win7下IE9访问QC
  • 原文地址:https://www.cnblogs.com/nyvi/p/8837012.html
Copyright © 2011-2022 走看看