zeus00456

导航

使用TimeUnit的睡眠代替Thread.sleep()

@

§1 各种睡法(写法)

TimeUnit.NANOSECONDS.sleep(1);//纳秒
TimeUnit.MICROSECONDS.sleep(1);//微秒
TimeUnit.MILLISECONDS.sleep(1);//毫秒
TimeUnit.SECONDS.sleep(1);//秒
TimeUnit.MINUTES.sleep(1);//分钟
TimeUnit.HOURS.sleep(1);//小时
TimeUnit.DAYS.sleep(1);//天

§2 睡姿(源码)

public void sleep(long timeout) throws InterruptedException {
    if (timeout > 0) {
        long ms = toMillis(timeout);
        int ns = excessNanos(timeout, ms);
        Thread.sleep(ms, ns);//最终还是这么睡的,但多了只是多了时间单位转换和验证
    }
}

§3 为什么要这么用

首先,性能上几乎没有影响,虽然多了调用方法栈等操作
下面是测试代码

import java.util.concurrent.TimeUnit;
public class TestSleep {
    public static void main(String[] args) throws InterruptedException {       
        sleepByTimeunit(10000);
        sleepByThread(10000);      
    }
    
    private static void sleepByTimeunit(int sleepTimes) throws InterruptedException {
        long start = System.currentTimeMillis();
        for(int i=0; i<sleepTimes; i++){
            TimeUnit.MILLISECONDS.sleep(10);
        }
        long end = System.currentTimeMillis();
        System.out.println("Total time consumed by TimeUnit.MILLISECONDS.sleep : " + (end - start));
    }
    
    private static void sleepByThread(int sleepTimes) throws InterruptedException {
        long start = System.currentTimeMillis();
        for(int i=0; i<sleepTimes; i++){
            Thread.sleep(10);
        }
        long end = System.currentTimeMillis();
        System.out.println("Total time consumed by Thread.sleep : " + (end - start));
    }
}

结果:

Total time consumed by TimeUnit.MILLISECONDS.sleep : 100068
Total time consumed by Thread.sleep : 100134
Difference : -- -66
Total time consumed by TimeUnit.MILLISECONDS.sleep : 100222
Total time consumed by Thread.sleep : 100077
Difference : -- +145

万次调用并没有差太多
其次,看起来更优雅,优雅这种形式的意义是更强的阅读性。可能有人认为 Thread.sleep() 写起来要比 TimeUnit.xxx.sleep() 简洁,那么这里需要解释一下,这里有个误会。
有上面想法的同学通常日常代码就是这么写的:

Thread.sleep(1000);
Thread.sleep(20 * 1000);

写法不能说不对,但质量(可读性)肯定是不高的,完整的写法应该是这样的

//在使用之前,你应该在你的TimeUtil工具类中定义时间单位常量
//当然,你也可以定义在使用的类中,如果你不嫌麻烦

/** 下面是一组时间单位 */
public static final long SECOND = 1000;
public static final long MINUTE = 60 * 1000; 

//接下来,如果操作比较集中,你需要考虑在你使用的类中静态导入
import static xx.xx.xx.xx.TimeUtil;

//然后你才能优雅的使用它

//通常这种操作需要注释为啥要睡一下,防止没仔细看你代码的同学帮你“优化”掉
Thread.sleep(10 * SECOND);

//如果你跳过了第二步,你的代码就是这样的
Thread.sleep(10 * TimeUtil.SECOND);

看起来很麻烦,但是,在使用Thread.sleep()的前提下,这确实是最优雅的方式。并且,一些代码非常良好的团队确实是这么要求的(毕竟代码相对于让机器去run,更重要的意义是给人看,为什么这么说,因为咱写的java,不是单片机demo)。
而上面这些工作,TimeUnit其实都帮你干了,你直接使用就是如上面那一大坨的效果。

本文内容引自 https://blog.51cto.com/stevex/1285767

posted on 2022-07-28 16:41  问仙长何方蓬莱  阅读(367)  评论(0编辑  收藏  举报