前言

Java程序中,我们时常会有需要使用到计时的需求,比如统计某一段程序运行时间,以此判断程序的效率,又例如统计用户操作的时间等等。因此,掌握好java计时功能的使用,非常关键,是每一个java开发者必学的内容。

新手常见的误区Sleep()

对很多初学java的新手来说,最简单的方法可能是使用Thread类中的自带方法sleep(int ms),单位为毫秒。
因其操作简单,只需要一个方法即可解决,需要计时多少毫秒就设定sleep()的参数。但是,使用sleep()有着诸多问题。
第一,它本身是一个线程的休眠方法,休眠也就意味着这个线程被暂时阻塞,无法工作;
第二,由于线程被休眠阻塞到重新执行的过程中需要经过算法调度,因此,实际等待的时间通常会略长于设定的毫秒数,这就导致计时的精度受到影响。

三种计时方法

1.使用System类中的currentTimeMillis()方法

这种应该是大家接触比较多的一个方法,学习Java se部分基本都会涉及到。
获取19701月1日0时0分0秒至今的毫秒数,于是我们可以这样获取经过的时间。

 		long millis1 = System.currentTimeMillis();
        //do something
        long millis2 = System.currentTimeMillis();
        long time=millis2-millis1;//经过的毫秒数

2.使用System类中的nanoTime()方法

这个方法的返回值为纳秒(nanosecond),它的计算和cpu的时钟周期有关,因此精度相对currentTimeMillis()更高,但是执行一次的耗时也会更高。返回值与系统的时间无关,甚至可能是负数,只能用来计算两次,求经过的时间。

		long millis1 = System.nanoTime();
        //do something
        long millis2 = System.nanoTime();
        long time=millis2-millis1;//经过的毫秒数

3.使用StopWatch类

StopWatch是位于org.springframework.util包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块。相对于前两种,在查看代码计时的时候更加方便。下面是一个简单的例子。

	StopWatch sw = new StopWatch("test");
     sw.start("task1");
     // do something
    Thread.sleep(160);
    sw.stop();
    sw.start("task2");
    // do something
    Thread.sleep(240);
    sw.stop();
    System.out.println("sw.prettyPrint()输出:");
    System.out.println(sw.prettyPrint());

关于计时的一些总结

三种方法中,首推的是第三种,因为前两种虽然写起来更轻松,却相对不好管理,在实际开发中,代码量大的时候,更容易混淆自己的思路。当然也是可以使用的。
对于计时,其实无论是哪种方法,都无法避免误差,实际精度也难免受限于硬件。不过对于大多数的使用上,毫秒级的精度对我们已经足够了。

更多推荐

快速上手,Java中的计时功能(三种方法解决)