JUC TimeUnit深入

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深入)