这是饥饿吗? [英] Is this starvation?
问题描述
我找到了一段线程似乎饿死的代码。下面是一个简化的例子。这是饥饿的一个例子吗?线程没有终止的原因是什么?
I found a piece of code where the thread seems to starve. Below is a simplified example. Is this an example for starvation? What is the reason why the thread does not terminate?
注意:将睡眠状态更改为1有时会导致终止。注释掉的Thread.yield()会解决问题(对我而言)。
Note: Changing the sleep to 1 will sometimes result in termination. The commented out Thread.yield() would solve the problem (for me).
public class Foo {
public static boolean finished = false;
public static void main(String[] args) {
Runnable worker = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finished = true;
}
};
new Thread(worker).start();
while (!finished) {
// Thread.yield();
}
}
}
推荐答案
您可能需要了解Java内存模型。多线程不只是关于交错线程的动作;它是关于一个线程到另一个线程的操作的可见性。
You probably need to get informed on the Java Memory Model. Multithreading isn't just about interleaving the actions of threads; it is about the visibility of actions by one thread to another.
在这个问题的底部是需要积极优化面子并发:任何确保线程之间内存一致性的机制都很昂贵,并且很多(大多数)数据不在线程之间共享。因此,未明确标记 volatile
或受锁保护的数据默认情况下被视为 thread-local (当然没有严格保证)。
At the bottom of this issue lies the need for aggressive optimization in the face of concurrency: any mechanism which ensures memory coherency between threads is expensive, and much (most) of the data is not shared between threads. Therefore the data not explicitly marked volatile
, or protected by locks, is treated as thread-local by default (without strict guarantees, of course).
在你的情况下,已完成
是一个这样的变量,如果它满意,可以被视为线程局部的运行时。它确实令人高兴,因为
In your case, finished
is such a variable which is allowed to be treated as thread-local if it pleases the runtime. It does please it because the
while (!finished);
循环可以重写为
if (!finished) while (true);
如果你在循环中做了任何重要的工作,它会表现得更好,因为读取已完成
不会不必要地重复,因此可能会破坏整个CPU缓存行。
If you did any important work inside the loop, it would perform a bit better because the read of finished
wouldn't be needlessly repeated, thus possibly destroying one whole CPU cache line.
以上讨论应该足够了回答你的直接问题,这是饥饿:循环没有完成的原因不是饥饿,而是无法看到其他线程的写入。
The above discussion should be enough to answer your immediate question, "is this starvation": the reason the loop doesn't finish is not starvation, but the inability to see the write by the other thread.
这篇关于这是饥饿吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!