【问题标题】:Confusion between sleep() and wait() [duplicate]sleep()和wait()之间的混淆[重复]
【发布时间】:2015-08-09 02:38:43
【问题描述】:

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

我在准备 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) 我已经在 t1 上调用了 sleep() 5 秒,它正在对 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() 是个坏主意。这两者的原因是什么?

【问题讨论】:

标签: java multithreading sleep wait


【解决方案1】:

好的,我会试着回答这个问题。

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

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

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

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

【讨论】:

  • 第一个问题只是对可能性的怀疑。感谢您的回答
  • @vicky96 - 不鼓励使用sleep()进行计时,因为中断可能正确发生但是调度程序可能不会立即调度线程的执行。在时间过去之前,不会安排睡眠线程。
【解决方案2】:

Java 中等待和睡眠的区别:

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

【讨论】:

  • 都是真的,但你没有说其中任何一个是如何被使用的。 Thread.sleep() 用于计时。这是ScheduledThreadPoolExecutor 和任何其他更高级别设施的基础的原始操作,它使事情在指定时间发生。 Object.wait()Object.notify() 用于线程之间的通信。它们是一个线程可以用来告诉另一个线程“我已经完成了你正在等待的事情”的最低级别机制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2021-12-08
  • 2020-11-02
  • 2016-09-22
  • 2015-06-01
相关资源
最近更新 更多