Java日期时间API系列5-----Jdk7及以前的日期时间类TimeUnit在并发编程中的应用

TimeUnit是一个时间单位枚举类,主要用于多线程并发编程,时间单元表示给定粒度单元的时间持续时间,并提供实用程序方法来跨单元转换,以及在这些单元中执行计时和延迟操作。

1.时间单位换算

(1)支持的单位

TimeUnit.DAYS          //
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //
TimeUnit.MILLISECONDS  //毫秒
TimeUnit.MICROSECONDS  //微秒
TimeUnit.NANOSECONDS  //纳秒

(2)转换方法,例如:TimeUnit.HOURS 的转换源码

    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; }
    }

(3)使用举例

//小时转换为秒
long sec = TimeUnit.HOURS.toSeconds(1);
System.out.println("sec:" + sec);

// 另一种形式
long sec2 = TimeUnit.SECONDS.convert(1, TimeUnit.HOURS);
System.out.println("sec2:" + sec2);

输出结果:

sec:3600
sec2:3600

2.计时操作

计时操作需要2个参数:数值和单位TimeUnit。

(1)Lock,tryLock,尝试获取锁50毫秒。

  Lock lock = ...;
   if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...

(2)线程池构造方法参数:keepAliveTime和unit

Java线程池ThreadPoolExecutor原理和用法,ThreadPoolExecutor构造方法:

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止;
unit:参数keepAliveTime的时间单位(TimeUnit);
 
例如:java.util.concurrent.Executors.newCachedThreadPool(ThreadFactory)
    public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>(),
                                      threadFactory);
    }
(3)ArrayBlockingQueue的poll方法,long和TimeUnit
java.util.concurrent.ArrayBlockingQueue.poll(long, TimeUnit)
        ArrayBlockingQueue<Long> arrayBlockingQueue = new ArrayBlockingQueue<>(100);
        for (long i = 0; i < 100; i++) {
            arrayBlockingQueue.add(i);
        }
        
        for (long i = 0; i < 100; i++) {
            try {
                System.out.println(arrayBlockingQueue.poll(50, TimeUnit.MILLISECONDS));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

3.延迟操作

(1)比如当前线程延迟5s

TimeUnit.SECONDS.sleep(5);

4.TimeUnit 与 Thread sleep的区别

(1)TimeUnit sleep的原理

    public void sleep(long timeout) throws InterruptedException {
        if (timeout > 0) {
            long ms = toMillis(timeout);
            int ns = excessNanos(timeout, ms);
            Thread.sleep(ms, ns);
        }
    }

TimeUnit sleep的底层调用了Thread.sleep。

(2)区别:TimeUnit sleep使用起来更方便,更易懂

比如:比如当前线程延迟5s:

使用Thread.sleep

Thread.sleep(5000);
// 或者
Thread.sleep(5*1000);

使用TimeUnit

TimeUnit.SECONDS.sleep(5);
原文地址:https://www.cnblogs.com/xkzhangsanx/p/12043881.html