java.lang.Thread.sleep()方法和java.lang.Object.wait()方法之间的区别

java.lang.Thread.sleep()

  1. sleep()方法为Thread类定义的静态方法,因此需要通过Thread类调用该方法;
  2. 调用sleep()方法将会导致当前正在执行线程休眠特定的时间;
  3. 一般情况下,调用sleep()方法后进入休眠状态的线程并不会释放其持有的对象锁。

java.lang.Object.wait()

  1. wait()方法是Object类定义的普通方法,因此任何对象都可调用该方法;
  2. wait()方法、notify()方法和notifyAll()方法都需要先获取到对象上的锁后才能调用,否则会报java.lang.IllegalMonitorStateException;
  3. 当线程调用对象的wait()方法后,线程将进入等待状态并释放其持有的该对象上的锁(线程仍然持有其它对象的锁);
  4. 当对象的notify()方法、notifyAll()方法被调用,或者线程被中断,或者线程等待了wait()方法指定的等待时间(如果为wait(0),则只有对象的notify()方法或notifyAll()方法被调用后线程才会退出等待状态)后,线程将退出等待状态,并和其它线程公平的竞争对象上的锁,一旦线程成功获取到对象锁,线程将从wait()方法调用返回,对象的同步状态和线程的同步状态将和wait()方法调时一样。
### TIMED_WAITING 状态的含义 在 Java 中,线程状态 `TIMED_WAITING` 表示线程正在等待一段时间后恢复执行。这种状态通常发生在调用了一些特定的方法时,例如 `Thread.sleep(long millis)`、`Object.wait(long timeout)` 或 `LockSupport.parkNanos(long nanos)` 等[^1]。这些方法会让线程进入计时等待状态,直到指定的时间到期或被其他线程唤醒。 当线程处于 `TIMED_WAITING` 状态时,它不会消耗 CPU 资源,因为此时线程并未参与运行或竞争资源。相反,它只是暂时挂起,等待计时器到期或外部事件触发其恢复执行[^4]。 --- ### 在对象监视器上的表现 在对象监视器上,`TIMED_WAITING` 状态的线程通常会表现出以下特征: 1. **调用 `Object.wait(long timeout)` 方法** 当线程调用了带超时参数的 `wait(long timeout)` 方法时,它会释放当前持有的对象锁,并进入 `TIMED_WAITING` 状态。在此期间,线程不会占用 CPU 资源,而是等待超时时间到达或被其他线程通过 `notify()` 或 `notifyAll()` 唤醒[^3]。 2. **调用 `Thread.sleep(long millis)` 方法** 如果线程调用了 `Thread.sleep(long millis)`,它会暂停执行一段时间,但并不会涉及对象监视器的操作。因此,在这种情况下,线程不会与任何对象锁相关联[^1]。 3. **调用 `LockSupport.parkNanos(long nanos)` 方法** 类似于 `Thread.sleep()`,`LockSupport.parkNanos()` 也会让线程进入 `TIMED_WAITING` 状态,但它主要用于更底层的线程同步机制,例如在实现自定义锁时使用。同样,这种方式也不会直接与对象监视器交互[^4]。 --- ### 原因分析 线程进入 `TIMED_WAITING` 状态的原因可以归结为以下几种情况: 1. **显式调用计时等待方法** 线程显式调用了如 `Thread.sleep(long millis)`、`Object.wait(long timeout)` 或 `LockSupport.parkNanos(long nanos)` 等方法,导致其进入计时等待状态[^4]。 2. **线程间协作需求** 在某些场景下,线程需要等待特定条件满足后再继续执行。例如,生产者-消费者模型中,消费者线程可能会调用 `Object.wait(long timeout)` 来等待生产者完成任务并通知其继续执行[^4]。 3. **定时任务执行** 在定时任务中,线程可能需要等待一定时间后才开始执行任务。例如,调度器中的线程可能会调用 `Thread.sleep(long millis)` 来延迟任务的启动。 --- ### 解决方法 针对 `TIMED_WAITING` 状态的解决方法主要取决于具体的应用场景问题描述: 1. **检查线程是否正常退出** 如果发现某些线程长时间处于 `TIMED_WAITING` 状态且未退出,可能是由于逻辑错误导致的。例如,`Object.wait(long timeout)` 的超时时间设置过长,或者根本没有被唤醒。 2. **优化线程间的协作机制** 在多线程协作场景中,确保线程之间的通信机制(如 `notify()` `notifyAll()`)正确实现。避免出现线程等待超时而无法被唤醒的情况。 3. **减少不必要的计时等待** 如果线程频繁调用 `Thread.sleep(long millis)` 或类似方法,可能会对性能造成影响。在这种情况下,可以考虑优化代码逻辑,减少不必要的等待时间[^1]。 4. **监控线程状态** 使用工具如 `jstack` 或 `Java VisualVM` 监控线程的状态变化,及时发现并解决问题。例如,通过线程转储查看哪些线程进入了 `TIMED_WAITING` 状态以及原因[^2]。 --- ### 示例代码 以下是一个简单的示例,展示线程如何进入 `TIMED_WAITING` 状态并被唤醒: ```java public class TimedWaitingExample { public static void main(String[] args) throws InterruptedException { Object lock = new Object(); Thread worker = new Thread(() -> { synchronized (lock) { System.out.println("Thread is waiting..."); try { lock.wait(5000); // 线程进入 TIMED_WAITING 状态 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread woke up!"); } }); worker.start(); Thread.sleep(2000); // 主线程等待 2 秒 synchronized (lock) { lock.notify(); // 唤醒等待的线程 } } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值