Java Thread 类基础用法
在 Java 中,Thread 类是多线程编程的核心。
线程创建
创建线程主要有两种逻辑:继承 Thread 类或实现 Runnable 接口。
- 方式 1:继承 Thread 类,重写 run()
class MyThread extends Thread {
// 重写 run(),定义线程执行逻辑
@Override
public void run() {
System.out.println("子线程执行:" + Thread.currentThread().getName());
}
}
// 使用
public class Demo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start(); // 调用 start() 启动线程(不能直接调用 run())
}
}
- 方式 2:实现 Runnable 接口,传给 Thread
// 实现 Runnable 接口
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("子线程执行:" + Thread.currentThread().getName());
}
}
// 使用
public class Demo {
public static void main(String[] args) {
// 把 Runnable 实例传给 Thread
Thread t = new Thread(new MyRunnable());
t.start(); // 启动线程
}
}
线程中断
线程中断不是强制停止线程,而是一种协作机制,即给线程发一个'请停止'的信号。
void interrupt():标记线程为'中断状态'boolean isInterrupted():判断线程是否处于中断状态- 若线程在 sleep/wait/join 时被中断,会抛出 InterruptedException,且中断状态会被清除
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
// 检测中断状态
System.out.println("线程运行中...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// 捕获中断异常后,中断状态会被清除,需手动终止循环
System.out.println("线程被中断");
Thread.currentThread().interrupt(); // 重新标记中断(可选)
break;
}
}
});
t.start(); // 主线程 1 秒后中断子线程
Thread.sleep(1000);
t.interrupt();
线程等待 (Join)
有时主线程需要等待子线程执行完毕后再继续执行,这时可以使用 join()。
t.join():当前线程会进入阻塞状态,直到线程 t 执行结束。join(long millis):设置最大等待时间,如果超时线程还没结束,当前线程就不再等待。
Thread t = new Thread(() -> {
System.out.println("子线程开始执行");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
System.out.println("子线程执行完毕");
});
t.start();
// 主线程等待 t 执行完(最多等 3 秒)
t.join(3000);
System.out.println("主线程继续执行");
线程休眠 (Sleep)
static void sleep(long millis):让当前线程暂停指定时间(不会释放锁),抛出 InterruptedException
System.out.println("开始休眠");
try {
Thread.sleep(2000); // 当前线程休眠 2 秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠结束");
获取线程实例
在编写通用代码(尤其是 Runnable 中)时,常需要知道是谁在运行。
Thread.currentThread():返回代码当前正在执行的那个线程对象的引用。- 常用操作:获取线程 ID (getId())、获取线程名称 (getName()) 等。
// 获取当前线程(这里是 main 线程)
Thread mainThread = Thread.currentThread();
System.out.println("当前线程名:" + mainThread.getName()); // 输出"main"
// 子线程实例
Thread t = new Thread(() -> {
Thread current = Thread.currentThread();
System.out.println("子线程名:" + current.getName()); // 输出"Thread-0"
});
t.start();
Java 线程的几种状态
线程状态一共有几种?
Java 线程共有 6 种状态:
- NEW (新建)
- RUNNABLE (可运行)
- BLOCKED (阻塞)
- WAITING (等待)
- TIMED_WAITING (超时等待)
- TERMINATED (终止)
每种状态的含义与切换条件
1. NEW (新建)
- 含义:创建了线程对象(new Thread()),但尚未调用 start() 方法。
- 切换:调用 start() 方法后,进入 RUNNABLE 状态。
2. RUNNABLE (可运行)
- 含义:Java 将操作系统中的'就绪(Ready)'和'运行中(Running)'两种状态统称为 RUNNABLE。处于该状态的线程可能正在 CPU 上执行,也可能正在等待操作系统分配时间片。
- 切换:
- 就绪 -> 运行:获得 CPU 时间片。
- 运行 -> 就绪:CPU 时间片用完,或主动调用 Thread.yield()。
3. BLOCKED (阻塞)
- 含义:线程正在等待获取一个排他锁(如进入 synchronized 代码块/方法),但该锁目前被其他线程持有。
- 切换:
- RUNNABLE -> BLOCKED:尝试进入 synchronized 区域失败。
- BLOCKED -> RUNNABLE:其他线程释放锁,当前线程成功竞争到锁。
4. WAITING (等待)
- 含义:线程处于无限期的等待状态,不会被分配 CPU 时间,必须等待其他线程显式地唤醒。
- 切换:
- RUNNABLE -> WAITING:调用 Object.wait()(不带参数)、Thread.join()(不带参数)或 LockSupport.park()。
- WAITING -> RUNNABLE:其他线程调用 Object.notify()、notifyAll() 或 LockSupport.unpark()。
5. TIMED_WAITING (超时等待)
- 含义:与 WAITING 类似,但在指定的时间后会自动唤醒,不需要其他线程显式唤醒。
- 切换:
- RUNNABLE -> TIMED_WAITING:调用 Thread.sleep(ms)、Object.wait(ms)、Thread.join(ms) 等带时间参数的方法。
- TIMED_WAITING -> RUNNABLE:时间结束,或被提前唤醒(如 notify())。
6. TERMINATED (终止)
- 含义:线程已经执行完毕(run() 方法正常结束)或因异常退出了执行。
- 切换:线程一旦进入此状态,生命周期结束,不可再次启动(再次调用 start() 会抛出异常)。

