一、TimeUnit

  • TimeUnit 是 java.util.concurrent 包中的一个枚举类,它提供了一种可读性更强、更易于使用的时间单位转换和线程操作工具

二、TimeUnit 枚举常量

  • TimeUnit 包含了从纳秒到天一共 7 个时间单位常量
枚举常量 说明
NANOSECONDS 纳秒 (十亿分之一秒)
MICROSECONDS 微秒 (百万分之一秒)
MILLISECONDS 毫秒 (千分之一秒)
SECONDS
MINUTES 分钟
HOURS 小时
DAYS

三、TimeUnit 时间单位转换

1、基本介绍
  1. 将 sourceDuration 从 sourceUnit 单位转换为当前 TimeUnit 单位
convert(long sourceDuration, TimeUnit sourceUnit)
  1. 将当前 TimeUnit 单位下的 duration 转换为目标单位
long toNanos(long duration)

long toMicros(long duration)

long toMillis(long duration)

long toSeconds(long duration)

long toMinutes(long duration)

long toHours(long duration)

long toDays(long duration)
2、演示
  1. convert 方法
long seconds = TimeUnit.SECONDS.convert(3, TimeUnit.MINUTES);

System.out.println(seconds);
# 输出结果

180
  1. toXxx 系列方法
long seconds = TimeUnit.MINUTES.toSeconds(5);

System.out.println(seconds);

long millis = TimeUnit.SECONDS.toMillis(3);

System.out.println(millis);

long hours = TimeUnit.MINUTES.toHours(90);

System.out.println(hours);
# 输出结果

300
3000
1
long hours = TimeUnit.HOURS.convert(1, TimeUnit.DAYS);

System.out.println("1 day = " + hours + " hours");

long seconds = TimeUnit.MINUTES.toSeconds(30);

System.out.println("30 minutes = " + seconds + " seconds");

long micros = TimeUnit.MILLISECONDS.toMicros(1000);

System.out.println("1000 milliseconds = " + micros + " microseconds");
# 输出结果

1 day = 24 hours
30 minutes = 1800 seconds
1000 milliseconds = 1000000 microseconds

四、TimeUnit 基于时间的线程操作

1、基本介绍
  1. 让当前线程休眠指定的时间,它是 Thread.sleep 方法的可读性替代品
void sleep(long timeout) throws InterruptedException
  1. 在对象监视器 obj 上等待最多 timeout 时间,调用此方法前,必须先获得 obj 的锁,它是 obj.wait 方法的可读性替代品
void timedWait(Object obj, long timeout) throws InterruptedException
  1. 等待目标线程 thread 终止,最多等待 timeout 时间,它是 thread.join 方法的可读性替代品
void timedJoin(Thread thread, long timeout) throws InterruptedException
2、演示
  1. sleep 方法
try {
    TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
    e.printStackTrace();
}
  1. timedWait 方法
private static int sharedValue = 0;

private static final Object lock = new Object();

private static final int CONSUMER_TIMEOUT = 400;
private static final int PRODUCER_WAIT_TIME = 500;
Thread consumer = new Thread(() -> {
    synchronized (lock) {
        try {
            System.out.println("消费者: 开始等待数据,超时时间为 " + CONSUMER_TIMEOUT + " ms...");

            TimeUnit.MILLISECONDS.timedWait(lock, CONSUMER_TIMEOUT);

            if (sharedValue == 0) {
                System.out.println("消费者: 等待超时,未收到数据!");
            } else {
                System.out.println("消费者: 收到数据: " + sharedValue);
            }
        } catch (InterruptedException e) {
            System.out.println("消费者: 被中断");
            Thread.currentThread().interrupt();
        }
    }
});

Thread producer = new Thread(() -> {
    try {
        TimeUnit.MILLISECONDS.sleep(PRODUCER_WAIT_TIME);

        synchronized (lock) {
            sharedValue = 42;
            System.out.println("生产者: 生产了数据: " + sharedValue);
            lock.notify();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});

consumer.start();
producer.start();

try {
    consumer.join();
    producer.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}
# 输出结果

消费者: 开始等待数据,超时时间为 400 ms...
消费者: 等待超时,未收到数据!
生产者: 生产了数据: 42
  1. timedJoin 方法
Thread backgroundThread = new Thread(() -> {
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
backgroundThread.start();

try {
    TimeUnit.SECONDS.timedJoin(backgroundThread, 3);
} catch (InterruptedException e) {
    e.printStackTrace();
}

if (backgroundThread.isAlive()) {
    System.out.println("backgroundThread 还在运行");
}
# 输出结果

backgroundThread 还在运行
3、非替代演示
  1. Thread.sleep 方法
try {
    Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
  1. obj.wait 方法
private static int sharedValue = 0;

private static final Object lock = new Object();

private static final int CONSUMER_TIMEOUT = 400;
private static final int PRODUCER_WAIT_TIME = 500;
Thread consumer = new Thread(() -> {
    synchronized (lock) {
        try {
            System.out.println("消费者: 开始等待数据,超时时间为 " + CONSUMER_TIMEOUT + " ms...");

            lock.wait(CONSUMER_TIMEOUT);

            if (sharedValue == 0) {
                System.out.println("消费者: 等待超时,未收到数据!");
            } else {
                System.out.println("消费者: 收到数据: " + sharedValue);
            }
        } catch (InterruptedException e) {
            System.out.println("消费者: 被中断");
            Thread.currentThread().interrupt();
        }
    }
});

Thread producer = new Thread(() -> {
    try {
        Thread.sleep(PRODUCER_WAIT_TIME);

        synchronized (lock) {
            sharedValue = 42;
            System.out.println("生产者: 生产了数据: " + sharedValue);
            lock.notify();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
});

consumer.start();
producer.start();

try {
    consumer.join();
    producer.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}
# 输出结果

消费者: 开始等待数据,超时时间为 400 ms...
消费者: 等待超时,未收到数据!
生产者: 生产了数据: 42
  1. thread.join 方法
Thread backgroundThread = new Thread(() -> {
    try {
        Thread.sleep(5 * 1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
backgroundThread.start();

try {
    backgroundThread.join(3000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

if (backgroundThread.isAlive()) {
    System.out.println("backgroundThread 还在运行");
}
# 输出结果

backgroundThread 还在运行
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐