wait()和yield()之间的区别

到目前为止,我对wait()和yield()方法的理解是,当线程不执行任何任务并让CPU执行其他某个线程时,将调用yield()。 当某个线程处于暂停状态并且通常用于同步的概念时,会使用wait()。 但是,我不明白它们的功能差异,我不确定我所理解的是对还是错。 有人可以解释他们之间的区别(除了他们出席的包)。


他们是不是都在做同样的任务 - 等待其他线程可以执行?

甚至没有关闭,因为yield()不会等待任何东西。

每个线程都可以处于许多不同的状态之一:运行意味着线程实际上在CPU上运行,Runnable意味着没有任何东西阻止线程运行,除非可以运行CPU。 所有其他的州可以被归入一个名为阻塞的类别。 被阻塞的线程是一个线程,它在可以运行之前正在等待某些事情发生。

操作系统会定期抢占正在运行的线程:每隔一段时间(大多数操作系统上每秒10次和每秒100次)每个正在运行的线程的操作系统标记,并说:“轮到你了,转到运行队列“(即将状态从运行状态更改为可运行状态),然后让运行队列头部的任何线程使用该CPU(即再次运行)。

当你的程序调用Thread.yield() ,它对操作系统说:“我仍然有工作要做,但它可能不像其他线程那样重要。请将我发送到现在运行队列。“ 如果有线程可用的CPU可用,那么它就会继续运行(即yield()调用将立即返回)。

另一方面,当你的程序调用foobar.wait()时,它会告诉操作系统“阻塞我,直到其他线程调用foobar.notify()

屈服首先在非抢先式操作系统上实现,并且在非抢先式线程库中实现。 在只有一个CPU的计算机上,多于一个线程运行的唯一方式是线程明确地相互排斥。

屈服对于忙碌的等待也很有用。 这就是一个线程等待事情发生的地方,坐在一个紧密的循环中,一遍又一遍地测试相同的条件。 如果条件依赖于某个其他线程来完成某些工作,则等待的线程会每次在循环中产生()以便让其他线程完成其工作。

既然我们拥有抢占式和多处理器系统以及为我们提供更高级同步对象的库,那么基本上没有理由为什么应用程序需要再调用yield()


wait是等待一个条件。 在查看该方法时,这可能不会引起注意,因为完全取决于您来定义它是什么样的条件。 但是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变量,则此循环会中断。


第一个不同之处在于yield()是一个Thread方法, wait()位于原始Object方法在thread继承所有类,在形状中,在后台(使用java doc)

wait()

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

yield()

向调度程序提示当前线程愿意产生当前使用的处理器。 调度程序可以自由地忽略这个提示。

在这里你可以看到yield()和wait()之间的区别

链接地址: http://www.djcxy.com/p/92149.html

上一篇: difference between wait() and yield()

下一篇: Thread.sleep() implementation