TimeUnit使用和解析

一、TimeUnit.sleep

1.1 使用

睡眠一段时间,通常使用的是Thread.sleep方法,代码如下:

public static void testSleep() throws InterruptedException {
    Thread.sleep(1000 * 60 * 5);
}

上述代码表示睡眠5分钟,可读性不好。如果使用TimeUnit,代码如下:

public static void testTimeUnitSleep() throws InterruptedException {
    TimeUnit.MINUTES.sleep(5);
}

TimeUnit.sleep的可读性明显高于Thread.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); // 调用Thread.sleep
        }
}

本质就是对Thread.sleep(long millis)的一个封装,提供了时间转换操作。

二、TimeUnit.timedWait

2.1 使用

	public static void testTimeUnitWait() throws InterruptedException {
		Object lock = new Object();
		synchronized (lock) {
			TimeUnit.MINUTES.timedWait(lock, 5);
		}
	}

2.2 代码解析

 public void timedWait(Object obj, long timeout) throws InterruptedException {
        if (timeout > 0) {

            long ms = toMillis(timeout);

            int ns = excessNanos(timeout, ms);

            obj.wait(ms, ns);
        }
}

本质就是对Object.wait(long timeout)的一个封装,,提供了时间转换操作。

三、TimeUnit.timedJoin

3.1 使用

	public static void testTimeUnitJoin() throws InterruptedException {
		Thread thread = new Thread(() -> {
			System.out.println("run");
			try {
				TimeUnit.MINUTES.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Over run.");
		});

		thread.start();
		TimeUnit.MINUTES.timedJoin(thread, 5);
		System.out.println("Over Main.");
	}

3.2 代码解析

 public void timedJoin(Thread thread, long timeout) throws InterruptedException {

        if (timeout > 0) {

            long ms = toMillis(timeout);

            int ns = excessNanos(timeout, ms);

            thread.join(ms, ns);
        }
}

本质就是对Thread.join(long millis)的一个封装,,提供了时间转换操作。

四、TimeUnit.toXXX

4.1 简单使用

System.out.println(TimeUnit.SECONDS.toMinutes(10)); // 0

System.out.println(TimeUnit.SECONDS.toMinutes(65)); // 1

System.out.println(TimeUnit.MILLISECONDS.toMicros(1)); // 1毫秒=1000微秒

System.out.println(TimeUnit.MICROSECONDS.toNanos(1)); // 1微秒=1000纳秒

4.2 解析

TimeUnit提供了以下方法来转换时间:

toNanos(long)

toMicros(long)

toMillis(long)

toSeconds(long)

toMinutes(long)

toHours(long)

toDays(long)

注:从小单位转换成大单位用的整除,直接取整,比如65秒为1分钟多一点,那么转换成分钟只取整数。以下为SECONDS.toMinutes实现,C4=60000000000,C3=1000000000

public long toMinutes(long d) { return d/(C4/C3); }

五、TimeUnit部分代码

TimeUnit本质就是一个枚举,是学习枚举的好例子。

public enum TimeUnit {

    /**

     * Time unit representing one thousandth of a microsecond

     */

    NANOSECONDS {

        public long toNanos(long d)   { return d; }

        public long toMicros(long d)  { return d/(C1/C0); }

        public long toMillis(long d)  { return d/(C2/C0); }

        public long toSeconds(long d) { return d/(C3/C0); }

        public long toMinutes(long d) { return d/(C4/C0); }

        public long toHours(long d)   { return d/(C5/C0); }

        public long toDays(long d)    { return d/(C6/C0); }

        public long convert(long d, TimeUnit u) { return u.toNanos(d); }

        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }

    },

 

    /**

     * Time unit representing one thousandth of a millisecond

     */

    MICROSECONDS {

        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }

        public long toMicros(long d)  { return d; }

        public long toMillis(long d)  { return d/(C2/C1); }

        public long toSeconds(long d) { return d/(C3/C1); }

        public long toMinutes(long d) { return d/(C4/C1); }

        public long toHours(long d)   { return d/(C5/C1); }

        public long toDays(long d)    { return d/(C6/C1); }

        public long convert(long d, TimeUnit u) { return u.toMicros(d); }

        int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }

    },

 

    /**

     * Time unit representing one thousandth of a second

     */

    MILLISECONDS {

        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }

        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }

        public long toMillis(long d)  { return d; }

        public long toSeconds(long d) { return d/(C3/C2); }

        public long toMinutes(long d) { return d/(C4/C2); }

        public long toHours(long d)   { return d/(C5/C2); }

        public long toDays(long d)    { return d/(C6/C2); }

        public long convert(long d, TimeUnit u) { return u.toMillis(d); }

        int excessNanos(long d, long m) { return 0; }

    },

 

    /**

     * Time unit representing one second

     */

    SECONDS {

        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }

        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }

        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }

        public long toSeconds(long d) { return d; }

        public long toMinutes(long d) { return d/(C4/C3); }

        public long toHours(long d)   { return d/(C5/C3); }

        public long toDays(long d)    { return d/(C6/C3); }

        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }

        int excessNanos(long d, long m) { return 0; }

    },

 

    /**

     * Time unit representing sixty seconds

     */

    MINUTES {

        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }

        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }

        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }

        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }

        public long toMinutes(long d) { return d; }

        public long toHours(long d)   { return d/(C5/C4); }

        public long toDays(long d)    { return d/(C6/C4); }

        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }

        int excessNanos(long d, long m) { return 0; }

    },

 

    /**

     * Time unit representing sixty minutes

     */

    HOURS {

        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }

        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }

        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }

        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }

        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }

        public long toHours(long d)   { return d; }

        public long toDays(long d)    { return d/(C6/C5); }

        public long convert(long d, TimeUnit u) { return u.toHours(d); }

        int excessNanos(long d, long m) { return 0; }

    },

 

    /**

     * Time unit representing twenty four hours

     */

    DAYS {

        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }

        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }

        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }

        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }

        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }

        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }

        public long toDays(long d)    { return d; }

        public long convert(long d, TimeUnit u) { return u.toDays(d); }

        int excessNanos(long d, long m) { return 0; }

    };

 

    // Handy constants for conversion methods

    static final long C0 = 1L;

    static final long C1 = C0 * 1000L;

    static final long C2 = C1 * 1000L;

    static final long C3 = C2 * 1000L;

    static final long C4 = C3 * 60L;

    static final long C5 = C4 * 60L;

    static final long C6 = C5 * 24L;

 

    static final long MAX = Long.MAX_VALUE;

 

    /**

     * Scale d by m, checking for overflow.

     * This has a short name to make above code more readable.

     */

    static long x(long d, long m, long over) {

        if (d >  over) return Long.MAX_VALUE;

        if (d < -over) return Long.MIN_VALUE;

        return d * m;

    }

你可能感兴趣的:(Java)