美文网首页
JUC TimeUnit深入

JUC TimeUnit深入

作者: 小王_min | 来源:发表于2021-03-15 15:53 被阅读0次

    TimeUnit是什么?

    JUC的一部分,表示给定粒度单位的持续时间,并提供实用方法以跨单位进行转换,并在这些单位中执行计时和延迟操作。

    包含的时间单位

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

    时间单位之间的转化

    • 1000 * NANOSECONDS(纳秒) = 1 * MICROSECONDS(微秒)
    • 1000 * MICROSECONDS(微秒) = 1 * MILLISECONDS(毫秒)
    • 1000 * MILLISECONDS(毫秒) = 1 * SECONDS(秒)
    • 60 * SECONDS(秒) = 1 * MINUTES(分)
    • 60 * MINUTES(分) = 1 * HOURS(时)
    • 24 * HOURS(时) = 1 * DAYS(天)

    包含的方法

    1. public long convert(long sourceDuration, TimeUnit sourceUnit)
      convert源码
    • sourceDuration:指的是需要转化的时间量
    • sourceUnit:指的是需要转化的时间单位

    这边的方法在每个枚举中都有相应的实现,最终会将传入的时间转换成方法调用的单位。
    例如TimeUnit.SECONDS.convert(1, TimeUnit.HOURS),此方法就是将「1小时」转为以秒为单位,所以结果为3600

    1. public long toNanos(long duration)
      toNanos源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以纳秒为单位的数值。
    例如TimeUnit.MICROSECONDS.toNanos(1),将1微秒转为纳秒为单位,所以结果为1000

    1. public long toMicros(long duration)
      toMicros源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以微秒为单位的数值。
    例如TimeUnit.MILLISECONDS.toMicros(1),将1毫秒转为微秒为单位,所以结果为1000

    1. public long toMillis(long duration)
      toMillis源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以毫秒为单位的数值。
    例如TimeUnit.SECONDS.toMillis(1),将1秒转为微秒为单位,所以结果为1000

    1. public long toSeconds(long duration)
      toSeconds源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以秒为单位的数值。
    例如TimeUnit.MINUTES.toSeconds(1),将1分钟转为秒为单位,所以结果为60

    1. public long toMinutes(long duration)
      toMinutes源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以分钟为单位的数值。
    例如TimeUnit.HOURS.toMinutes(1),将1小时转为分钟为单位,所以结果为60

    1. public long toHours(long duration
      toHours源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以小时为单位的数值。
    例如TimeUnit.DAYS.toHours(1),将1天转为小时为单位,所以结果为24

    1. public long toDays(long duration)
      toDays源码
    • duration:指的是时间量(单位取决于调用方)

    此方法是将duration转为以天为单位的数值。
    例如TimeUnit.HOURS.toDays(48),将48小时转为天为单位,所以结果为2

    1. abstract int excessNanos(long d, long m)
      excessNanos源码
    • d:指的是时间量(单位取决于调用方)
    • m:指的是毫秒数

    取得时间量(单位取决于调用方)的纳秒数
    使用场景:TimeUnit#timedWait

    1. public void timedWait(Object obj, long timeout)
      timedWait源码
    • obj:要超时等待的对象
    • timeout:超时时间

    timedWait原理(本质上就是Object.wait()):

    1. 获取毫秒数
    2. 获取纳秒数
    3. obj.wait()


      wait源码
      wait源码

    等待阻塞时底层调用的是Object.wait,而这个wait的超时时间最小支持ns级。所以在调用的时候取得纳秒数,如果999999>纳秒数>0,那么就多等待1ms。

    1. public void timedJoin(Thread thread, long timeout)
      timedJoin源码
    • thread:需要join的线程
    • timeout:超时时间

    同理timedWait,同样是调用Thread.join(),同样最小支持ns级

    join源码
    1. public void sleep(long timeout)
      sleep源码
    • timeout:超时时间

    同理timedWait,同样是调用Thread.join(),同样最小支持ns级

    sleep源码

    为啥TimeUnit要对sleepwait额外封装呢?

    首先来看看如何使用?

    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            new Thread(() -> {
                // do something
    
                try {
                    // 1. 使用TimeUnit睡眠2s
                    TimeUnit.SECONDS.sleep(2);
                    // 2. 使用Thread.sleep()
                    Thread.sleep(2 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
    

    从以上的代码可以很明显地看出,使用TimeUnit的方式会更加的简洁且语义明确。

    使用的场景

    1. 所有需要对时间进行单位之间的转化action或者是有使用时间的场景,例如:reentrantLock.tryLock(1, TimeUnit.SECONDS);
    2. sleep()wait()join()相关的操作,使用TimeUnit的封装方法可使得程序更加可读。

    相关文章

      网友评论

          本文标题:JUC TimeUnit深入

          本文链接:https://www.haomeiwen.com/subject/atvkcltx.html