Java Thread 类核心技术笔记

Java Thread 类核心技术笔记

一、概述

Java 中的 java.lang.Thread 类是线程实现的核心基础,它封装了线程的所有核心属性和行为,允许我们在 Java 程序中创建和管理多线程执行流程。Java 虚拟机(JVM)支持多线程并发执行,每个 Thread 实例对应一个独立的执行线程,线程的执行逻辑封装在 run() 方法中,且不能直接调用 run() 方法启动线程 (直接调用仅相当于普通方法调用,不会创建新线程),必须通过 start() 方法触发 JVM 对线程的调度。

二、核心重要非方法内容

1. 线程的两种创建方式

Thread 类本身实现了 Runnable 接口,创建线程有两种标准方式,本质都是封装执行逻辑 run() 方法:

  • 方式一:继承 Thread 类,重写 run() 方法
    优点:实现简单,可直接通过 this 访问当前线程的属性和方法;
    缺点:Java 单继承限制,子类无法再继承其他类,耦合度较高。
  • 方式二:实现 Runnable 接口,将实例传入 Thread 构造器
    优点:规避单继承限制,解耦执行逻辑和线程管理,便于线程池复用任务逻辑;
    缺点:无法直接访问线程属性,需通过 Thread.currentThread() 获取当前线程实例。

2. 线程的优先级

Thread 类定义了 3 个优先级常量,用于提示 JVM 调度线程的优先级(仅为提示,不保证严格按照优先级执行,具体依赖操作系统和 JVM 实现):

  • MIN_PRIORITY = 1:最低优先级
  • NORM_PRIORITY = 5:默认优先级(新创建的线程继承父线程的优先级,主线程默认是 5)
  • MAX_PRIORITY = 10:最高优先级

注意:线程优先级不能超出 1-10 的范围,否则会抛出 IllegalArgumentException,且线程组会限制线程的最大优先级,设置的优先级不能超过线程组的最大优先级。

3. 守护线程(Daemon Thread)

线程分为用户线程守护线程

  • 用户线程:默认创建的线程(非守护线程),JVM 会等待所有用户线程执行完毕后才会退出;
  • 守护线程:为用户线程提供辅助服务(如垃圾回收线程 GC、定时器后台线程),当所有用户线程执行完毕,JVM 会直接退出,不会等待守护线程执行完成。

关键特性:setDaemon(boolean on) 方法必须在线程启动(start())前调用,否则会抛出 IllegalThreadStateException

4. 线程的 6 种状态(State 枚举)

Thread 类通过 State 枚举定义了线程的生命周期,一个线程在任意时刻只能处于一种状态,状态转换由 JVM 控制,无法手动干预:

  • NEW:新建状态,线程对象已创建,但尚未调用 start() 方法,未进入 JVM 线程调度队列;
  • RUNNABLE:可运行状态,包含「就绪」和「运行中」两种子状态,线程已启动,等待操作系统分配 CPU 资源(就绪)或正在执行 run() 方法(运行中);
  • BLOCKED:阻塞状态,线程等待获取监视器锁(synchronized 锁),无法执行;
  • WAITING:无限等待状态,线程无超时等待其他线程执行特定操作(如 Object.wait()Thread.join() 无参版),需被其他线程唤醒才能进入就绪状态;
  • TIMED_WAITING:定时等待状态,线程带超时时间等待(如 Thread.sleep(long)Object.wait(long)),超时时间到会自动唤醒进入就绪状态;
  • TERMINATED:终止状态,线程的 run() 方法执行完毕或因未捕获异常终止,生命周期结束。

三、常用核心方法(精选 7 种)

1. void start() - 启动线程

  • 核心作用:触发 JVM 创建新线程,将线程状态从 NEW 转换为 RUNNABLE,等待 CPU 调度执行,线程启动后会自动调用 run() 方法
  • 注意事项:一个线程只能调用一次 start() 方法,重复调用会抛出 IllegalThreadStateException

2. void run() - 线程执行逻辑封装

  • 核心作用:封装线程的核心执行逻辑,JVM 调度线程后会自动调用该方法,无需手动调用;
  • 注意事项:
    • 直接调用 run() 方法不会创建新线程,仅相当于在当前线程中执行一个普通方法;
    • 若创建 Thread 时传入了 Runnable 实例,run() 方法会调用 Runnable 实例的 run() 方法,否则 run() 方法为空,无任何执行逻辑。

3. static Thread currentThread() - 获取当前执行线程

  • 核心作用:静态方法,返回当前正在执行该方法的线程实例,可用于获取线程的名称、优先级、状态等属性;
  • 典型场景:在 Runnable 实现类中获取当前线程(无 this 引用),或在多线程环境中打印当前执行线程标识。

示例:

java 复制代码
public static void main(String[] args) {
    Thread thread = new Thread(() -> {
        // 获取当前执行的线程
        Thread current = Thread.currentThread();
        System.out.println("当前线程名称:" + current.getName());
    }, "测试线程");
    thread.start();
}

4. static void sleep(long millis) - 线程休眠

  • 核心作用:静态方法,让当前执行线程进入 TIMED_WAITING 状态,休眠指定的毫秒数(millis),休眠期间不会释放已持有的监视器锁(synchronized 锁);
  • 注意事项:
    • 会抛出 InterruptedException 受检异常,需捕获或声明抛出(休眠期间线程若被中断,会触发该异常并清除中断状态);
    • 休眠时间受操作系统定时器精度影响,并非绝对准确,休眠结束后线程进入 RUNNABLE 状态,等待 CPU 调度;
    • 重载方法 sleep(long millis, int nanos) 支持纳秒级休眠,本质是对毫秒数的补充,最终仍转换为毫秒级休眠。

5. void interrupt() - 中断线程

  • 核心作用:向目标线程发送中断请求,不会强制终止线程 ,仅设置线程的中断标志位为 true
  • 中断的处理逻辑:
    • 若线程处于 sleep()wait()join() 等阻塞状态,会抛出 InterruptedException,并清除中断标志位(标志位变为 false);
    • 若线程处于正常运行状态,仅设置中断标志位,需由线程自身通过 isInterrupted()interrupted() 检测中断标志位,自行决定是否终止执行(优雅中断);
  • 典型场景:实现优雅的线程退出,替代已废弃的 stop() 方法(stop() 会强制终止线程,可能导致资源泄露、数据不一致)。

6. boolean isInterrupted() - 检测线程中断状态

  • 核心作用:实例方法,返回目标线程的中断标志位状态,不会清除中断标志位
  • 对比:静态方法 interrupted() 也可检测中断状态,但会清除中断标志位(调用后标志位变为 false),且仅能检测当前执行线程的中断状态。

7. void join() - 线程等待

  • 核心作用:实例方法,让当前执行线程等待目标线程执行完毕(进入 WAITING 状态),再继续执行当前线程的后续逻辑;
  • 注意事项:
    • 重载方法 join(long millis)join(long millis, int nanos) 支持超时等待,超时后当前线程不再等待,进入 RUNNABLE 状态;
    • 会抛出 InterruptedException 受检异常,等待期间当前线程若被中断,会触发该异常;
    • 等待期间不会释放当前线程已持有的监视器锁。

示例:

java 复制代码
public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(() -> {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行:" + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();
    // 主线程等待子线程执行完毕后,再执行后续逻辑
    thread.join();
    System.out.println("主线程执行完毕");
}

四、补充:已废弃的危险方法

Thread 类中的 stop()suspend()resume() 方法已被废弃,存在严重安全隐患,禁止在开发中使用:

  1. stop():强制终止线程,会释放线程所有持有的锁,可能导致共享数据处于不一致状态;
  2. suspend():暂停线程,且不会释放持有的锁,容易导致死锁(其他线程无法获取该锁,而 resume() 若在获取锁前调用,会导致线程永久暂停);
  3. resume():恢复被 suspend() 暂停的线程,与 suspend() 配套使用,存在死锁风险。

五、总结

  1. Thread 类是 Java 多线程的基础,线程启动依赖 start() 方法,执行逻辑封装在 run() 方法中,有继承 Thread 和实现 Runnable 两种创建方式;
  2. 线程有 6 种生命周期状态,由 JVM 自动转换,核心状态转换包括「新建→可运行→终止」「可运行→阻塞/等待→可运行」;
  3. 常用核心方法聚焦于线程启动(start())、休眠(sleep())、中断(interrupt())、等待(join())和状态检测(currentThread()isInterrupted()),且需避免使用已废弃的危险方法;
  4. 守护线程为用户线程提供辅助,JVM 退出不等待守护线程,优先级仅为 JVM 调度提示,不保证严格执行。
相关推荐
LGL6030A2 小时前
Java学习历程26——线程安全
java·开发语言·学习
pcm1235672 小时前
设计C/S架构的IM通信软件(4)
java·c语言·架构
老师用之于民2 小时前
【DAY21】Linux软件编程基础&Shell 命令、脚本及系统管理实操
linux·运维·chrome·经验分享·笔记·ubuntu
iFeng的小屋2 小时前
【2026年新版】Python根据小红书关键词爬取所有笔记数据
笔记·爬虫·python
山岚的运维笔记2 小时前
SQL Server笔记 -- 第14章:CASE语句
数据库·笔记·sql·microsoft·sqlserver
宵时待雨2 小时前
STM32笔记归纳8:时钟
笔记·stm32·单片机·嵌入式硬件
带刺的坐椅2 小时前
用 10 行 Java8 代码,开发一个自己的 ClaudeCodeCLI?你信吗?
java·ai·llm·agent·solon·mcp·claudecode·skills
Nebula_g2 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
HAPPY酷3 小时前
构造与析构:C++ 中对象的温柔生灭
java·jvm·c++