ThreadLocal 应用:封装一个好用的代码执行耗时统计工具

平常项目开发中,会需要处理这样的需求:统计某段代码,或者某个方法的执行耗时。而且这个需求实现起来并不难,很多小伙伴都会编写如下代码

public static void main(String[] args) {
    
    
    // 代码执行耗时统计
    // 记时开始-start
    long start = System.currentTimeMillis();

    // 模拟代码实际执行时间(休眠800毫秒)
    try {
    
    
        TimeUnit.MILLISECONDS.sleep(800);
    } catch (InterruptedException e) {
    
    
        e.printStackTrace();
    }

    // 记时结束-end
    long end = System.currentTimeMillis();
    System.out.println("代码执行完成.共耗时:" + (end - start) + "毫秒.");
}

执行结果
代码执行完成.共耗时:802毫秒.
Process finished with exit code 0

像上面这样的代码,初步看来没有什么问题,需求已经实现了!但是我们要是细想,这样的代码真的 ok 吗?

答案肯定是不 ok 的,这样的代码不够优雅!我们其实有更好的实现方式,今天这篇文章,我就给你分享一个好用的代码执行耗时统计工具,你可以借鉴用到你们的项目中

1. 工具类实现分析

首先我们尝试思考一下,要编写这样一个代码执行耗时工具类,需要考虑哪些点呢?

  • 既然是一个工具类,肯定是大家都要用的,要考虑并发场景下线程安全的问题
  • 该工具类提供的能力,最好是能支持嵌套统计代码执行耗时

需求提出来了,实现其实非常简单,要考虑并发场景下线程安全的问题,通常有两种解决方案

  • 加锁,能保证线程安全,但是性能肯定上不去了 —> 因此这不是推荐的方案
  • ThreadLocal,与当前线程绑定,不存在共享问题,即解决了线程安全的问题,又不影响性能 —> 空间换时间,是推荐的方案

2. 代码:TimerStat

实现思路清楚以后,代码其实非常简单,我就直接上代码,你一看就明白了。

public class TimerStat {
    
    

    /**
     * 当前线程绑定ThreadLocal
     */
    private static final ThreadLocal<List<Long>> TIMER_STAT_THREAD_LOCAL = new ThreadLocal();

    /**
     * 耗时统计-开始
     * @return
     */
    public static long start(){
    
    
        // 系统当前时间
        long time = System.currentTimeMillis();
        // 从threadLocal取值
        List<Long> times = TIMER_STAT_THREAD_LOCAL.get();
        // 第一次统计耗时
        if(Objects.isNull(times)){
    
    
            times = new ArrayList<>();
            TIMER_STAT_THREAD_LOCAL.set(times);
        }

        // 将time添加到list,支持嵌套
        times.add(time);

        return time;
    }

    /**
     * 耗时统计-结束
     * @return
     */
    public static long end(){
    
    
        // 从threadLocal取值
        List<Long> times = TIMER_STAT_THREAD_LOCAL.get();
        if(Objects.nonNull(times)){
    
    
            // 支持嵌套,从最后一个开始取值
            Long time = times.remove(times.size() - 1);
            long end = System.currentTimeMillis();
            time = end - time;

            return time;
        }

        return -1L;
    }
}

使用代码示例

 // 代码执行耗时统计
// 记时开始-start
TimerStat.start();

// 模拟代码实际执行时间(休眠800毫秒)
try {
    
    
    TimeUnit.MILLISECONDS.sleep(800);
} catch (InterruptedException e) {
    
    
    e.printStackTrace();
}

System.out.println("TimerStat统计.代码执行完成.共耗时:" + TimerStat.end() + "毫秒.");

执行结果
TimerStat统计.代码执行完成.共耗时:801毫秒.

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_43842093/article/details/129785116