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

2. public long toNanos(long duration)

toNanos源码

  • duration:指的是时间量(单位取决于调用方)

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

3. public long toMicros(long duration)

toMicros源码

  • duration:指的是时间量(单位取决于调用方)

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

4. public long toMillis(long duration)

toMillis源码

  • duration:指的是时间量(单位取决于调用方)

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

5. public long toSeconds(long duration)

toSeconds源码

  • duration:指的是时间量(单位取决于调用方)

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

6. public long toMinutes(long duration)

toMinutes源码

  • duration:指的是时间量(单位取决于调用方)

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

7. public long toHours(long duration

toHours源码

  • duration:指的是时间量(单位取决于调用方)

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

8. public long toDays(long duration)

toDays源码

  • duration:指的是时间量(单位取决于调用方)

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

9. abstract int excessNanos(long d, long m)

excessNanos源码

  • d:指的是时间量(单位取决于调用方)
  • m:指的是毫秒数

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

10. 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。

11. public void timedJoin(Thread thread, long timeout)

timedJoin源码

  • thread:需要join的线程
  • timeout:超时时间

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

join源码

12. 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的封装方法可使得程序更加可读。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值