Java 线程常用方法
·
一、线程生命周期相关方法
作用:控制线程从创建到终止的全流程,是线程操作的基础。
| 方法 | 作用 | 调用者 | 注意事项 |
|---|---|---|---|
start() |
启动新线程(JVM 创建线程并调用run()) |
线程对象 | ① 仅能调用 1 次,重复调用抛IllegalThreadStateException;② 直接调用run()是普通方法,不启动新线程。 |
run() |
线程执行体(定义任务逻辑) | 线程对象 | 需通过重写Thread或传入Runnable定义;无需手动调用(由start()触发)。 |
isAlive() |
判断线程是否存活(启动后未终止) | 线程对象 | 未start()或已终止的线程返回false。 |
join()join(long millis) |
当前线程等待目标线程执行完毕(或超时) | 目标线程对象 | ① 如t.join():主线程等待t执行完再继续;② 本质是通过wait()实现,会释放锁。 |
示例:start() vs run() + join()
public class ThreadLifecycle {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
// 子线程任务:循环输出
for (int i = 0; i < 3; i++) {
System.out.println("子线程执行:" + i);
try { Thread.sleep(500); } // 模拟耗时
catch (InterruptedException e) {}
}
}, "子线程");
// 1. 启动新线程(JVM调用run())
t.start();
// 若直接调用t.run(),会在主线程中执行,不创建新线程
// 2. 主线程等待子线程执行完毕
t.join(); // 阻塞主线程,直到t执行结束
System.out.println("主线程:子线程已结束,我继续执行");
}
}
/* 输出:
子线程执行:0
子线程执行:1
子线程执行:2
主线程:子线程已结束,我继续执行
*/
二、线程控制与中断方法
作用:控制线程执行节奏(暂停、让出 CPU)或通过中断机制协作终止线程。
| 方法 | 作用 | 调用者 | 注意事项 |
|---|---|---|---|
sleep(long millis) |
当前线程暂停指定毫秒(让出 CPU) | 静态方法(Thread) |
① 不释放同步锁(synchronized);② 时间到后回到就绪状态;③ 可被interrupt()中断,抛InterruptedException。 |
yield() |
当前线程让出 CPU,重新参与调度 | 静态方法(Thread) |
① 仅为 JVM 调度建议,不一定生效;② 不释放锁,适合同优先级线程礼让。 |
interrupt() |
设置线程中断标志(非强制终止) | 线程对象 | ① 若线程阻塞(sleep/wait等),抛InterruptedException并清除标志;② 需线程内部判断标志并处理终止。 |
isInterrupted() |
判断线程是否被中断(不清除标志) | 线程对象 | 线程内部用:while(!isInterrupted())控制退出逻辑。 |
interrupted() |
判断当前线程是否被中断(清除标志) | 静态方法(Thread) |
用于捕获异常后重置中断状态(如Thread.interrupted())。 |
示例:sleep()与interrupt()协作
public class ThreadControl {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
System.out.println("子线程:开始休眠10秒");
Thread.sleep(10000); // 休眠(阻塞状态)
} catch (InterruptedException e) {
// 被interrupt()中断时触发
System.out.println("子线程:被中断,休眠结束");
// 异常会清除中断标志,此处输出false
System.out.println("中断标志:" + Thread.currentThread().isInterrupted());
}
});
t.start();
// 主线程3秒后中断子线程
try { Thread.sleep(3000); } catch (InterruptedException e) {}
t.interrupt(); // 设置中断标志,唤醒阻塞的子线程
}
}
/* 输出:
子线程:开始休眠10秒
子线程:被中断,休眠结束
中断标志:false
*/
三、线程通信方法(Object类)
作用:多线程间协作(如生产者 - 消费者模型),必须在同步块 / 方法中使用(依赖锁)。
| 方法 | 作用 | 调用者 | 注意事项 |
|---|---|---|---|
wait()wait(long timeout) |
释放锁并进入等待状态(直到被唤醒 / 超时) | 同步锁对象 | ① 必须在synchronized(锁对象)中调用;② 唤醒后需重新竞争锁;③ 用while循环判断条件(防虚假唤醒)。 |
notify() |
唤醒一个等待当前锁的线程(随机) | 同步锁对象 | ① 需在同步块中调用;② 唤醒后线程需等当前线程释放锁才能执行。 |
notifyAll() |
唤醒所有等待当前锁的线程 | 同步锁对象 | 适用于资源充足时,唤醒全部等待者(如库存补充后唤醒所有消费者)。 |
示例:生产者 - 消费者模型(wait()+notify())
public class ThreadCommunication {
private static int count = 0; // 共享资源(库存)
private static final Object lock = new Object(); // 同步锁
// 生产者:增加库存
static class Producer extends Thread {
@Override
public void run() {
synchronized (lock) {
count++; // 生产
System.out.println("生产者:库存=" + count);
lock.notify(); // 唤醒等待的消费者
}
}
}
// 消费者:消耗库存
static class Consumer extends Thread {
@Override
public void run() {
synchronized (lock) {
// 循环判断(防虚假唤醒:即使被意外唤醒,仍需检查条件)
while (count == 0) {
try {
System.out.println("消费者:等待库存...");
lock.wait(); // 释放锁,进入等待
} catch (InterruptedException e) {}
}
count--; // 消费
System.out.println("消费者:消费后库存=" + count);
}
}
}
public static void main(String[] args) {
new Consumer().start(); // 消费者先启动(等待库存)
new Producer().start(); // 生产者生产后唤醒消费者
}
}
/* 输出:
消费者:等待库存...
生产者:库存=1
消费者:消费后库存=0
*/
四、线程属性方法
作用:设置 / 获取线程的标识、优先级、守护状态等属性。
| 方法 | 作用 | 调用者 | 注意事项 |
|---|---|---|---|
setName(String)/getName() |
设置 / 获取线程名称(调试用) | 线程对象 | 名称仅用于标识(如日志输出),无功能影响。 |
setPriority(int)/getPriority() |
设置 / 获取优先级(1-10,默认 5) | 线程对象 | ① 优先级高的线程更可能被调度(非绝对);② 范围:MIN_PRIORITY(1)~MAX_PRIORITY(10)。 |
setDaemon(boolean)/isDaemon() |
设置 / 判断守护线程(后台线程) | 线程对象 | ① 必须在start()前设置;② 依赖用户线程:所有用户线程结束,守护线程自动终止(如 GC 线程)。 |
示例:守护线程(后台线程)
public class DaemonThread {
public static void main(String[] args) {
Thread daemon = new Thread(() -> {
// 守护线程任务:无限循环(仅守护线程可安全使用)
while (true) {
System.out.println("守护线程运行中...");
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
});
daemon.setDaemon(true); // 标记为守护线程(必须在start前)
daemon.start();
// 主线程(用户线程)运行3秒后结束
try { Thread.sleep(3000); } catch (InterruptedException e) {}
System.out.println("主线程结束,守护线程自动终止");
}
}
/* 输出(约3秒后停止):
守护线程运行中...
守护线程运行中...
守护线程运行中...
主线程结束,守护线程自动终止
*/
五、方法的对比
| 对比项 | 关键差异 |
|---|---|
start() vs run() |
start()启动新线程;run()是普通方法,在当前线程执行。 |
sleep() vs wait() |
sleep不释放锁(Thread方法);wait释放锁(Object方法,需同步块)。 |
notify() vs notifyAll() |
notify唤醒一个线程;notifyAll唤醒所有线程(均需同步块)。 |
interrupt() 作用 |
不直接终止线程,仅设置中断标志;需线程通过isInterrupted()主动响应。 |
sleep () vs wait () 区别(聚焦「锁与系统资源」)
1. sleep () 的关键特性(重点)
- 让出系统资源(CPU):无论是否加锁,调用
sleep()都会让当前线程暂停,释放 CPU 时间片(让其他线程有机会获得 CPU 执行)—— 这是 “让出系统资源” 的核心含义。- 是否释放锁?分场景:
- 非线程安全(不加锁):没有锁可释放,其他线程能正常执行(因为 CPU 被让出了)。
- 线程安全(加锁,同步块 / 方法内):不释放锁(抱着锁睡)。此时虽然 CPU 被让出,但其他线程若需要同一把锁,会被阻塞(无法执行同步代码)。
2. wait () 的关键特性
- 必须在加锁场景(同步块 / 方法)中调用:否则直接抛异常。
- 既让出系统资源(CPU),又释放锁:调用
wait()后,当前线程会释放持有的锁,其他线程可以获取锁执行同步代码;同时线程进入等待状态,需被notify()/notifyAll()唤醒。总结
sleep():无论是否加锁,都会让出 CPU(系统资源);但加锁时不释放锁(抱着锁睡),其他线程拿不到锁就执行不了同步代码;不加锁时,其他线程能正常执行。
wait():必须在加锁场景用,既让出 CPU,又释放锁,其他线程能抢锁执行同步代码,需被 notify 唤醒。
更多推荐

所有评论(0)