Awa*_*ani 9 java multithreading
到目前为止,我对wait()和yield()方法的理解是,当线程没有执行任何任务并让CPU执行其他一些线程时,会调用yield().当一些线程被搁置并且通常用于同步的概念时,使用wait().但是,我无法理解其功能的差异,我不确定我所理解的是对还是错.有人可以解释它们之间的区别(除了它们存在的包装).
Sol*_*low 21
他们是不是都在做同样的任务 - 等待其他线程可以执行?
甚至还没有接近,因为yield()没有等待任何东西.
每个线程都可以处于多种不同状态之一: 运行意味着线程实际上在CPU上运行,Runnable意味着没有任何东西阻止线程运行,除了可能有CPU运行的可用性.所有其他状态都可以归为一个名为阻止的类别.被阻塞的线程是一个在可以运行之前等待某些事情发生的线程.
操作系统定期抢占运行线程:每隔一段时间(大多数操作系统每秒10次,每秒100次),每个运行线程的操作系统标记都说"轮到你了,转到后面运行队列'(即,将状态从运行更改为可运行).然后它允许运行队列头部的任何线程使用该CPU(即再次运行).
当你的程序调用时Thread.yield(),它会对操作系统说:"我还有工作要做,但它可能没有其他线程正在做的工作那么重要.请立即将我发送到运行队列的后面. " 如果有一个可用的CPU供线程运行,那么它实际上将继续运行(即,yield()调用将立即返回).
foobar.wait()另一方面,当你的程序调用时,它会向操作系统说"阻止我直到其他一些线程调用foobar.notify().
Yielding首先在非抢占式操作系统和非抢占式线程库中实现.在只有一个CPU的计算机上,多个线程运行的唯一方法是线程明确地相互产生.
让步对于忙碌的等待也很有用.这就是一个线程通过紧紧的循环等待事情发生的地方,一遍又一遍地测试相同的条件.如果条件依赖于某个其他线程来做一些工作,那么等待线程每次都会在循环中产生(),以便让其他线程完成它的工作.
现在我们有了抢占和多处理器系统和库,为我们提供了更高级别的同步对象,基本上没有理由为什么应用程序需要再调用yield().
wait是等待条件.在查看方法时,这可能不会引起注意,因为完全取决于您定义它是什么样的条件.但是API试图通过要求您拥有您正在等待的对象的监视器来强制您正确使用它,这对于在多线程环境中进行正确的条件检查是必要的.
所以正确使用wait看起来像:
synchronized(object) {
while( ! /* your defined condition */)
object.wait();
/* execute other critical actions if needed */
}
Run Code Online (Sandbox Code Playgroud)
它必须与执行代码的另一个线程配对,如:
synchronized(object) {
/* make your defined condition true */)
object.notify();
}
Run Code Online (Sandbox Code Playgroud)
相反Thread.yield(),只是提示您的线程可能会在此时释放CPU.没有指定它是否实际执行任何操作,并且无论CPU是否已被释放,它都不会影响内存模型的语义.换句话说,它不会与正确访问共享变量所需的其他线程建立任何关系.
例如,以下循环访问sharedVariable(未声明volatile)可能永远运行,而不会注意到其他线程所做的更新:
while(sharedVariable != expectedValue) Thread.yield();
Run Code Online (Sandbox Code Playgroud)
虽然Thread.yield可能有助于其他线程运行(它们将在大多数系统上运行),但它不会强制重新读取sharedVariable共享内存的值.因此,如果没有其他构造强制执行内存可见性(例如,判断sharedVariable为)volatile,则此循环被破坏.
| 归档时间: |
|
| 查看次数: |
12220 次 |
| 最近记录: |