java wait()和yield()之间的差异

9vw9lbht  于 2023-02-14  发布在  Java
关注(0)|答案(4)|浏览(82)

到目前为止我对等待的理解()和收益率()方法是产量当线程没有执行任何任务时调用(),让CPU执行其他线程。wait()用于挂起某个线程,通常用于同步的概念中。但是,我不明白它们在功能上的区别,也不确定我所理解的是对还是错。有人能解释一下它们之间的区别吗(除了它们存在的 Package )。

sbdsn5lh

sbdsn5lh1#

它们不都在执行相同的任务吗等待其他线程执行?
甚至不接近,因为yield()不 * 等待 * 任何东西。
每个线程可以处于许多不同状态之一:Running 意味着线程实际上正在CPU上运行,Runnable 意味着没有任何东西阻止线程运行,除了CPU的可用性。所有其他状态都可以归为一个类别,称为 blocked。blocked线程是指在变为可运行之前等待某个事件发生的线程。
操作系统定期 * 抢占 * 正在运行的线程:有时候(在大多数操作系统上,每秒10次到100次之间),操作系统会标记每个正在运行的线程,并说:“轮到你了,转到运行队列的后面”(即,将状态从运行改为可运行),然后让运行队列头部的任何线程使用该CPU(即,再次运行)。
当程序调用Thread.yield()时,它对操作系统说:“我还有工作要做,但可能没有其他线程正在做的工作重要。请立即将我发送到运行队列的后面。”如果有可用的CPU供线程运行,那么它实际上将继续运行(即yield()调用将立即返回)。
另一方面,当你的程序调用foobar.wait()时,它对操作系统说:“阻止我,直到其他线程调用foobar.notify()
让步最早是在非抢占式操作系统和非抢占式线程库中实现的。在只有一个CPU的计算机上,多个线程运行的唯一方式是线程之间明确地让步。
Yielding对于 * 忙碌waiting* 也很有用。在这种情况下,一个线程坐在一个紧密的循环中,一遍又一遍地测试同一个条件,等待某个事情发生。如果这个条件依赖于其他线程来完成一些工作,那么等待的线程每次都会在循环中产生yield(),以便让其他线程完成它的工作。
现在我们有了抢占式和多处理器系统以及为我们提供更高级同步对象的库,基本上没有理由让应用程序再需要调用yield()

nfeuvbwi

nfeuvbwi2#

wait表示在某个条件下 waiting。在查看该方法时,这可能不会引起注意,因为它完全由您来定义它是什么类型的条件。但是API试图通过要求您拥有正在等待的对象的监视器来强制您正确使用它,这对于在多线程环境中进行正确的条件检查是必要的。
因此,wait的正确用法如下所示:

synchronized(object) {
  while( ! /* your defined condition */)
    object.wait();
  /* execute other critical actions if needed */
}

并且它必须与另一个线程配对,执行如下代码:

synchronized(object) {
  /* make your defined condition true */)
  object.notify();
}

相比之下,Thread.yield()只是一个提示,提示您的线程可能会在此时释放CPU。它没有指定它是否实际执行任何操作,并且无论CPU是否已被释放,它都不会影响内存模型的语义。换句话说,它不会创建与其他线程的任何关系,而这些关系是正确访问共享变量所必需的。
例如,以下访问sharedVariable(未声明为volatile)的循环可能永远运行,而不会注意到其他线程所做的更新:

while(sharedVariable != expectedValue) Thread.yield();

虽然Thread.yield可以帮助其他线程运行(它们在大多数系统上都会运行),但它 * 不 * 强制从共享内存中重新读取sharedVariable的值。因此,如果没有其他强制内存可见性的构造,例如将sharedVariable解封装为volatile,这个循环就会中断。

xmakbtuz

xmakbtuz3#

第一个区别是yield()是一个Thread方法,wait()Object方法的起源,继承于thread中的所有类,在形状中,在后台(使用java doc)

wait()

使当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法。换句话说,此方法的行为就像它只是执行调用wait(0)一样。

yield()

给调度程序的一个提示,提示当前线程愿意放弃当前对处理器的使用。调度程序可以忽略这个提示。
这里可以看到yield()和wait()之间的difference

wpx232ag

wpx232ag4#

Yield():当一个正在运行的线程被停止,把它的空间给另一个具有高优先级的线程时,这叫做Yield。这里正在运行的线程变成了runnable线程。
Wait():线程正在等待从另一个线程获取资源以继续执行。

相关问题