MST

星途 面试题库

面试题:Java中sleep和wait方法在线程状态转变上有何差异

请详细阐述在Java中,当一个线程分别调用sleep方法和wait方法后,线程的状态是如何转变的,以及这两种状态转变在系统资源占用和线程调度方面有什么不同。
20.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 线程状态转变
    • sleep方法
      • 当线程调用sleep方法后,线程会从运行状态(RUNNABLE)转变为阻塞状态(TIMED_WAITING)。经过指定的睡眠时间后,线程会重新回到可运行状态(RUNNABLE),等待CPU调度再次执行。例如,Thread.sleep(1000);会使当前线程进入TIMED_WAITING状态1秒钟,1秒后回到RUNNABLE状态。
    • wait方法
      • 当线程调用wait方法后,线程会从运行状态(RUNNABLE)转变为等待状态(WAITING)或TIMED_WAITING(如果调用的是带时间参数的wait方法)。处于等待状态的线程需要其他线程调用notifynotifyAll方法来唤醒,才会重新回到可运行状态(RUNNABLE)。例如,在一个同步块中Object obj = new Object(); obj.wait();,当前线程会进入WAITING状态,直到其他线程调用obj.notify();
  2. 系统资源占用和线程调度方面的不同
    • 系统资源占用
      • sleep方法:线程在TIMED_WAITING状态时,虽然不执行用户代码,但仍然持有它所占用的锁资源。例如,在一个同步方法中调用Thread.sleep(1000);,在这1秒内,该线程持有的锁不会被释放,其他需要该锁的线程无法进入同步代码块。
      • wait方法:线程在WAITINGTIMED_WAITING状态时,会释放它所占用的锁资源。例如,在同步块Object obj = new Object(); synchronized(obj){obj.wait();}中,线程进入WAITING状态时会释放obj锁,其他线程可以获取obj锁并进入同步块。
    • 线程调度
      • sleep方法:线程进入TIMED_WAITING状态后,不需要其他线程干预,只要睡眠时间结束,就会自动进入RUNNABLE状态,等待CPU调度执行。例如Thread.sleep(5000);,5秒后线程就可以再次竞争CPU资源。
      • wait方法:线程进入WAITINGTIMED_WAITING状态后,需要其他线程调用notifynotifyAll方法来唤醒,才会进入RUNNABLE状态。而且notify方法只会唤醒等待队列中的一个线程,notifyAll方法会唤醒等待队列中的所有线程,被唤醒的线程需要竞争锁资源,竞争成功后才能执行。例如,多个线程在obj上等待,调用obj.notify();只会唤醒其中一个线程去竞争锁。