风暴喷口应该进入sleep()还是yield()吗?

时间:2018-07-17 12:55:12

标签: concurrency apache-storm thread-sleep

nextTuple()的Storm文档说:

  

当没有元组发出时,有礼貌的是使nextTuple短时间睡眠(例如一毫秒),以免浪费过多的CPU。

Utils.class中似乎有一种方法:Utils.sleep(long millis)

但是,在Apache Storm本身提供的一个喷口MqttSpout中,使用了另一种方法:

public void nextTuple() {
    AckableMessage tm = this.incoming.poll();
    if(tm != null){
        ...
    } else {
        Thread.yield();
    }
}

我怀疑Storm的作者可能在这里犯了一个错误,因为Thread.yield()本身在文档中有以下注释:

  

向调度程序的提示,即当前线程愿意放弃对处理器的当前使用。调度程序可以随意忽略此提示。

  

很少使用此方法。

那我应该使用哪一个?我怀疑使用Thread.yield()会导致不必要的CPU使用。

1 个答案:

答案 0 :(得分:3)

你的嘴根本不应该睡觉。如果您在通话过程中没有发出任何声音,Storm将处理在nextTuple通话之间的睡眠,至少在我熟悉的版本(即1.0.0及更高版本)中。

请参阅https://github.com/apache/storm/blob/v1.2.2/storm-core/src/clj/org/apache/storm/daemon/executor.clj#L667以供参考。每次调用时,等待策略的默认实现都会休眠一个可配置的时间间隔(默认为1ms)。您可以用https://github.com/apache/storm/blob/v1.2.2/storm-core/src/jvm/org/apache/storm/Config.java#L1886控制间隔,也可以完全用https://github.com/apache/storm/blob/v1.2.2/storm-core/src/jvm/org/apache/storm/Config.java#L1879替换等待策略。

暴风雨2.0.0的行为会稍有不同(逐渐增加睡眠时间),但这是相同的基本思想。

我认为nextTuple的javadoc具有误导性,因此我们可能应该对其进行修改。我也不确定"title1"在mqtt喷口中正在做什么。自从添加喷口以来,似乎一直在那儿。如果您在其中一个邮件列表(https://storm.apache.org/getting-help.html)上提问,则作者仍然在身边,可能会知道其中的原因。

如果愿意,可以在https://issues.apache.org/jira/secure/Dashboard.jspa提出问题以解决此问题:)