催眠唤醒线程

  • 场景 : 希望中断线程执行, 一段时间后继续执行
    如某程序中的一个线程, 每分钟检查一次传感器状态,其他时间空闲。空闲时不占用CPU,过后则准备好在JVM选择它执行时继续执行。

  • 解决方案:

    • 使用 Thread 类的 sleep 方法
      • 此方法有一个整型参数表示线程挂起的 毫秒 数。
      • 睡眠时间结束、JVM分配CPU时间后,线程继续执行 sleep 方法后的指令。
    • 使用 TimeUnit 枚举类元素的 sleep 方法
      • 此方法使用 Thread 类的 sleep 方法使当前线程睡眠
      • 参数单位为 TimeUnit 中的单位(它会自动转成毫秒值)

任务

使用 sleep 方法每秒钟输出一次当前日期

实现

  • 线程类 (FileClock)

    • 在 run 方法中循环 10 次, 每次输出当前时间后 sleep 1 秒
        for (int i = 0; i < 10; i++) {
            System.out.printf("%s\n", new Date());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.out.println("The FileClock has been interrupted");
            }
        }
    
    • 如果被中断, 则输出中断信息 (被中断时清理资源是个好习惯)
  • 控制类 (Main)

    • 创建并启动 FileClock 线程 5 秒后,中断它
        FileClock clock = new FileClock();
        Thread thread = new Thread(clock);
        thread.start();
    
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        thread.interrupt();
    

工作原理

  • 调用 sleep 方法后,线程停止执行一段时间。在此期间,不消耗 CPU ,这样 CPU 可以执行其他任务。
  • 当线程在睡眠中被中断,sleep 方法立即抛出一个 InterruptedException 异常,而不是等睡醒了才抛出。

了解更多

Java concurrency API 的 yield 方法也可以让线程离开CPU。

  • 它告知 JVM 此 Thread 对象可以不用 CPU 了,但 JVM 并不一定要按它说的办(即仍让线程继续运行)。
  • 通常用于调试