"wait()"和"sleep()"在Java中的区别

46 浏览
0 Comments

"wait()"和"sleep()"在Java中的区别

线程中的wait()sleep()有何区别?

我理解wait()的线程仍处于运行模式并使用CPU周期,而sleep()则不会消耗任何CPU周期,这个理解正确吗?

为什么我们需要同时使用wait()sleep()

它们在低级别的实现中有何不同?

admin 更改状态以发布 2023年5月21日
0
0 Comments

一个尚未提到的关键区别是:

  • sleep()并不释放它在线程上持有的锁,

    synchronized(LOCK) {
        Thread.sleep(1000); // LOCK is held
    }
    

  • wait()会释放它在对象上持有的锁。

     synchronized(LOCK) {
         LOCK.wait(); // LOCK is not held
     }
    

0
0 Comments

一个wait可以被另一个线程通过在等待的监视器上调用notify而"唤醒",而sleep则不能。另外,wait(和notify)必须发生在一个synchronized块上的监视器对象上,而sleep则不需要:

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

此时正在执行的线程等待并释放监视器,另一个线程可以对相同的mon对象执行notify,第一个线程(假设它是唯一在监视器上等待的线程)将被唤醒。

synchronized (mon) { mon.notify(); }

如果有多个线程在等待监视器,您还可以调用notifyAll来唤醒全部线程。但是,只有一个线程能够获取监视器(请记住,在synchronized块中执行wait),其他线程将被阻塞直到它们可以获得监视器的锁。

另一个要点是,您在Object本身上调用wait(即,在对象的监视器上等待),而在Thread上调用sleep

另一个问题是可能会出现 wait 的虚假唤醒(即等待的线程在没有明显原因的情况下被唤醒)。应该像下面这样,在某个条件上忙等待(spin)的同时总是使用 wait:

synchronized {
    while (!condition) { mon.wait(); }
}

0