使用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其实都帮你干了,你直接使用就是如上面那一大坨的效果。