sleep()和wait()之间的混淆

时间:2015-05-27 06:55:27

标签: java multithreading sleep wait

这些是一些概念上的怀疑。

我在准备SCJP时读了一本书

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()上呼叫了t1 5秒钟,这对obj1做了一些工作。 t1 obj1上还有一些待完成的工作要做。 sleep()未释放obj1上的锁定。同时t2正在尝试访问obj1

但是,如果不能保证t1将再次运行,那么t2会永远等待的情况会出现吗?可以避免这种情况吗?

2)如果t1根据其任务对obj1进行了更改,请在wait()之间致电t1t2根据其工作介入并对obj1进行了更改。

t1再次运行时,它会变得一团糟,对吧?因为obj1的状态将是t2所做的任何事情,t1会在wait()被调用之前失去它所做的所有工作。

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

4)此外,我还读到了必须从同步上下文中调用wait()的内容,从同步上下文中调用sleep()是个坏主意。这两个原因是什么原因?

2 个答案:

答案 0 :(得分:1)

Java中等待和睡眠的区别:

  1. 在等待时等待释放锁定对象,而等待时睡眠不释放锁定。
  2. 等待通常在条件下完成,线程等待直到条件为真,而睡眠只是让你的线程处于睡眠状态。
  3. 仅在同步上下文中调用wait,而在没有synchronized块的情况下可以调用sleep。请参阅为什么要等待并通知需要从synchronized方法调用以获取更多详细信息。
  4. 在对象上调用wait,同时在Thread上调用sleep。请参阅为什么等待和通知是在对象类而不是Thread中定义的。
  5. 等待线程可以通过调用notify和notifyAll来唤醒,而无法通过调用notify方法唤醒休眠线程。

答案 1 :(得分:1)

好吧,我打算回答这个问题。

  1. 如果t1 从不再次运行,我会说内核的线程调度程序已损坏。我不知道你在哪里知道它永远不会再次运行。

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

  3. 您不理解wait()notify()。搜索关于他们的问题,有很多。

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