1. 初步理解:WAITING与TIMED_WAITING的基本定义
在Java线程生命周期中,WAITING和TIMED_WAITING是两种重要的等待状态。WAITING表示线程正在无限期地等待另一个线程执行特定操作,例如调用`Object.wait()`或`Thread.join()`时进入此状态。而TIMED_WAITING则表示线程将在指定的时间内暂停,常用方法包括`Thread.sleep(long millis)`或`Object.wait(long timeout)`。
两者的主要区别在于:WAITING需要显式唤醒(如通过`notify()`或`notifyAll()`),而TIMED_WAITING会在超时后自动恢复运行。
WAITING:无限期等待,需依赖通知机制唤醒。TIMED_WAITING:带超时的等待,超时后自动恢复。
2. 深入分析:WAITING与TIMED_WAITING的触发场景
为了更好地理解这两种状态的区别,我们可以通过具体的触发场景来分析:
状态触发方法唤醒方式WAITING`Object.wait()`, `Thread.join()`, `LockSupport.park()`显式调用`notify()`或`notifyAll()`TIMED_WAITING`Thread.sleep(long millis)`, `Object.wait(long timeout)`, `LockSupport.parkNanos(long nanos)`超时后自动恢复
从表中可以看出,WAITING状态下的线程完全依赖外部通知来唤醒,而TIMED_WAITING状态下的线程则具有一定的“自愈”能力,能够在超时后自行恢复。
3. 实践案例:代码示例与运行结果
以下是两个简单的代码示例,分别展示WAITING和TIMED_WAITING的状态:
// WAITING状态示例
public class WaitingExample {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread t = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread is in WAITING state");
lock.wait(); // 进入WAITING状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
synchronized (lock) {
lock.notify(); // 唤醒线程
}
}
}
// TIMED_WAITING状态示例
public class TimedWaitingExample {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
System.out.println("Thread is in TIMED_WAITING state");
Thread.sleep(2000); // 进入TIMED_WAITING状态
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
t.join(); // 等待线程结束
}
}
通过运行上述代码,可以观察到WAITING状态需要显式唤醒,而TIMED_WAITING状态会在2秒后自动恢复。
4. 高级探讨:性能优化与死锁风险
了解WAITING与TIMED_WAITING的区别对于优化并发程序性能至关重要。以下是一些关键点:
尽量减少WAITING状态的使用,因为其完全依赖外部通知,可能导致线程长时间阻塞。优先使用TIMED_WAITING状态,以避免因通知遗漏而导致的死锁问题。在设计多线程程序时,确保每个WAITING状态都有对应的唤醒逻辑。
以下是一个简单的流程图,展示了如何选择合适的等待状态: