关于java:sleep()和wait()之间的混淆

Confusion between sleep() and wait()

本问题已经有最佳答案,请猛点这里访问。

这是一些概念上的疑问。

我在为SCJP做准备的时候在一本书中读到了这个。

1
2
3
Just because a thread’s sleep() expires, and it wakes up, does not mean
it will return to running. It simply goes back to the runnable state.
So you can't rely on sleep() for an accurate timer.

假设我有线t1t2和一个对象obj1

1)我给sleep()打了5秒钟的电话,是关于t1的,它在obj1上做了一些工作。t1obj1上还有一些工作要做。sleep()不解除obj1上的锁。同时,t2正试图访问obj1

但是,如果不能保证t1会再次运行,那么会不会出现这样一种情况:t2会一直等待下去?这种情况可以避免吗?

2)如果t1正在根据其任务对obj1进行更改,在此期间,我在t1上调用wait()t2根据其工作介入并对obj1进行更改。

t1再次运行时,会很混乱,对吗?因为当时的obj1状态将是t2所做的一切,而t1将失去它在wait()被调用之前所做的一切工作。

3)wait()是一种非静态方法,如果一个线程引用了另一个线程,那么一个线程会导致另一个线程等待吗?有没有什么例子来理解这种应用?

4)我也读到了一些东西,wait()必须从同步上下文调用,从同步上下文调用sleep()是个坏主意。这两个原因是什么?


好吧,我要试着回答这个问题。

  • 如果t1再也不能运行,我会说内核的线程调度器坏了。我不知道你从哪里知道它再也不会运行了。

  • 如果有两个线程对一个对象进行更改,则需要确保它们的行为正常。例如,使用synchronized确保一次只有一个线程操作对象。您的示例很奇怪,因为您似乎暗示程序员不决定代码会发生什么。

  • 你不懂wait()notify()。找一个关于他们的问题,有很多。

  • wait()需要在同步上下文中才能获得对象监视器。同步上下文中的sleep()只是为想要进入的其他线程创建了一个不必要的块。


  • Java中等待与睡眠的区别:

  • 等待时释放对象的锁定,而睡眠时不释放等待时的锁定。
  • 等待通常是在条件下完成的,线程等待直到条件为真,而睡眠只是让线程进入睡眠状态。
  • 只有在没有同步块的情况下才能调用sleep时,才从同步上下文调用wait。有关更多详细信息,请参阅为什么wait和notify需要从synchronized方法调用。
  • 对对象调用wait,而对线程调用sleep。请参阅为什么在对象类而不是线程中定义wait和notify。
  • 等待线程可以通过调用notify和notifyall来唤醒,而休眠线程不能通过调用notify方法来唤醒。