TimeUnit类详解

简介: TimeUnit类详解

其类作者Doug Lea在其javadoc中写道:

A TimeUnit represents time durations at a given unit of granularity and provides utility methods to convert across units, and to perform timing and delay operations in these units. A TimeUnit does not maintain time information, but only helps organize and use time representations that may be maintained separately across various contexts. A nanosecond is defined as one thousandth of a microsecond, a microsecond as one thousandth of a millisecond, a millisecond as one thousandth of a second, a minute as sixty seconds, an hour as sixty minutes, and a day as twenty four hours.

解释:
TimeUnit表示给定粒度单位的持续时间,
常见的颗粒度有:
在这里插入图片描述

  • NANOSECONDS 纳秒
  • MICROSECONDS 微秒
  • MILLISECONDS 毫秒
  • SECONDS 秒
  • MINUTES 分
  • HOURS 时
  • DAYS 天

并提供跨单位转换以及在这些单位中执行计时和延迟操作的实用方法。时间单位不维护时间信息,只帮助组织和使用可以在不同上下文中单独维护的时间表示。纳秒定义为千分之一微秒,微秒定义为千分之一毫秒,毫秒定义为千分之一秒,分钟定义为六十秒,小时定义为六十分钟,一天定义为二十四小时。

其中以纳秒举例,如下:

在这里插入图片描述
方法中用的属性定义如下:
在这里插入图片描述

NANOSECONDS {
    
        public long toNanos(long d)   {
     return d; }   // 转换成纳秒
        public long toMicros(long d)  {
     return d/(C1/C0); }   // 转换成微秒
        public long toMillis(long d)  {
     return d/(C2/C0); }      // 转换成毫秒
        public long toSeconds(long d) {
     return d/(C3/C0); }      // 转换成秒
        public long toMinutes(long d) {
     return d/(C4/C0); }      // 转换成分
        public long toHours(long d)   {
     return d/(C5/C0); }      // 转换成时
        public long toDays(long d)    {
     return d/(C6/C0); }      // 转换成天
        // 例如,要将10分钟转换为纳秒,请使用:TimeUnit.NANOSECONDS.convert(10L, TimeUnit.MINUTES)
        // 参数:
        // d–给定源单元中的持续时间
        // u–d参数的单位(参数可以为如下类型:
        //                NANOSECONDS 纳秒、
        //                 MICROSECONDS 微秒、
        //                 MILLISECONDS 毫秒、
        //                 SECONDS 秒、
        //                 MINUTES 分、
        //                 HOURS 时、
        //                 DAYS 天)
        // 返回:
        // 此单位中转换的持续时间,如果转换将负溢出,则为Long.MIN_VALUE;如果转换将正溢出,则为Long.MAX_VALUE。
        public long convert(long d, TimeUnit u) {
     return u.toNanos(d); }
        // 用于计算等待、睡眠和加入的多余纳秒参数的实用程序。
        // 参数:
        // d–持续时间
        // m–毫秒数
        // 返回:
        // 纳秒数
        int excessNanos(long d, long m) {
     return (int)(d - (m*C2)); } 
    },

其中注意在使用convert方法的时候,将给定单位中的给定持续时间转换为此单位。从细粒度到粗粒度的转换会截断,因此会失去精度。例如,将999毫秒转换为秒将导致0。从粗粒度到细粒度的转换,参数在数值上会溢出,如果为负,则饱和为Long.MIN_VALUE;如果为正,则饱和为Long.MAX_VALUE。
同时上例中将10分钟转换为纳秒,也可以使用另外一种方法,在对应的枚举类对象中,直接调用转换方法,如下:

TimeUnit.MINUTES.toNanos( 10 );

对于excessNanos,其中颗粒度为纳秒、微秒对于该重写方法有具体的逻辑计算,颗粒度为毫秒、秒、分、时、天中该重写方法就都返回0了。
还有一个static long x(long d, long m, long over)方法如下:

static long x(long d, long m, long over) {
      
        if (d >  over) return Long.MAX_VALUE;
        if (d < -over) return Long.MIN_VALUE;
        return d * m;
    }

该方法是用来检查从粗粒度到细粒度的转换,参数在数值上是否会溢出(参数在数值上会溢出,如果为负,则饱和为Long.MIN_VALUE;如果为正,则饱和为Long.MAX_VALUE),没有溢出就取正常值。
比如枚举对象MICROSECONDS对于toNanos的重写方法如下,该方法的作用是把微秒转为为纳秒,其方法内部就调用了x()进行检查是否溢出,如下:
在这里插入图片描述

当然TimeUnit类中还有枚举对象没用重写的方法,如下:

timedWait
其内部还是调用了Object对象的wait()方法,只是转换为了对应的颗粒度,增加了可读性timedJoin
其内部还是调用了Thread对象的join()方法,只是转换为了对应的颗粒度,增加了可读性sleep
其内部还是调用了Thread类的sleep()方法,只是转换为了对应的颗粒度,增加了可读性

举例:

// 没有用TimeUnit类
public static void main(String[] args) {
       
 
        new Thread( new Runnable() {
       
 
            @Override
            public void run() {
       
                try {
       
                    Thread.sleep( 5 * 60 * 1000 );
                    System.out.println( "延时完成了");
                } catch (InterruptedException e) {
       
                    e.printStackTrace();
                }
            }
        }).start();  ;
    }

//用了TimeUnit类
public static void main(String[] args) {
       
 
        new Thread( new Runnable() {
       
 
            @Override
            public void run() {
       
                try {
       
                    TimeUnit.MINUTES.sleep( 5 );
                    System.out.println( "延时5分钟,完成了");
                } catch (InterruptedException e) {
       
                    e.printStackTrace();
                }
            }
        }).start();  ;
    }

可以看到延时五分钟的时候,有了TimeUnit类,我们不用再去进行时间的转换运算,Thread.sleep( 5 * 60 * 1000 );直接调用TimeUnit.MINUTES.sleep( 5 );即可,极大的增加了我们写代码的便捷性和可阅读性。

已完结
于2021.11.24 著
author:YuShiwen
目录
相关文章
|
9月前
|
Java
JAVARandom类
JAVARandom类
68 0
|
2月前
DataSourceConfig类
该类包含以下属性,前4个属性是必须由外部指定的,剩下的都是可以默认指定的。(如果pool.properties中没有说明,就是用默认值,约定大于配置的思想)DataSourceConfig类
|
3月前
|
存储 SQL 数据库连接
ConnectionProxy类
ConnectionProxy类的主要作用是用于代理真实的Conection(数据库连接类)。之所以要额外构建一个代理类,是因为我们需要对连接进行连接超时检查,也就是健康检查功能,所以我们需要额外一个类型为long的属性来存储连接被取出时的时间。另一个重要的原因是,对于Connection中的一些接口我们并不希望显式的暴露给外部去使用。就比如说Connection中的close方法,就不能显式的暴露给外部使用,因为Connection在连接池中需要被重复使用,我们希望关闭连接的操作是有连接池来负责。在ConnectionProxy中,需要代理Connection中的一些必要的方法。这个可以看具
|
9月前
|
存储 程序员 数据安全/隐私保护
C++类
C++类
63 0
|
9月前
|
存储 Java
JAVAObject类
JAVAObject类
57 0
|
8月前
|
存储 安全 C#
C# 类的深入指南
C# 类的深入指南
|
9月前
|
传感器 存储 调度
PowerManagerService类大致解读
PowerManagerService类大致解读
151 1
|
9月前
|
Java
JAVASystem类
JAVASystem类
41 0
|
9月前
|
Java 索引
JAVAStringBuilder类
JAVAStringBuilder类
43 0
|
9月前
|
存储 编译器 C++
c++类全面讲解
前言 这次主要讲类的基础、构造函数与析构函数的使用,以及继承和多态。
144 0