这是饥饿吗? [英] Is this starvation?

查看:100
本文介绍了这是饥饿吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了一段线程似乎饿死的代码。下面是一个简化的例子。这是饥饿的一个例子吗?线程没有终止的原因是什么?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆