代码之家  ›  专栏  ›  技术社区  ›  Hai Hoang

如何解决声纳问题“删除此呼叫以“等待”或将其移动到“while”循环中”?

  •  2
  • Hai Hoang  · 技术社区  · 6 年前

    我收到一个在遗留项目中修复声纳问题的请求,有这样一个代码段,对该函数的每次调用都将暂停50毫秒:

    synchronized(monitor) {
    
      [...]
    
      try {
    
        [...]
    
        Thread.sleep(config.getWaitTime()); // return 50
      } catch (SomeException e) {
        log.error(e.getMessage(), e);
      }
    
      [...]
    }
    

    Thread.sleep() wait() 因此,我将try块更改为:

    try {
    
      [..]
    
      monitor.wait(config.getWaitTime());
    } catch (SomeException e) {
      log.error(e.getMessage(), e);
    }
    

    Remove this call to "wait" or move it into a "while" loop ,我在多线程方面没有太多经验,因此我不确定我的修复是否正确:

    boolean wait = true;
    while (wait) {
      wait = false;
      monitor.wait(config.getWaitTime());
    }
    

    3 回复  |  直到 6 年前
        1
  •  1
  •   davidxxx    6 年前

    这是 while 看起来很无助:

    boolean wait = true;
    while (wait) {
      wait = false;
      monitor.wait(config.getWaitTime());
    }
    

    这个 虽然 世界各地的声明 wait() 语句用于检查 等等 true 但在你的情况下,它永远不会像你指定的那样等待 false 作为while主体的第一个语句。
    这个
    这是你的电话号码 Object.wait(long) javadoc

    线程也可以在不被通知、中断或删除的情况下唤醒 超时,所谓的虚假唤醒。但这种情况很少发生 在实践中,应用程序必须通过测试 如果条件不满足,则继续等待。


    您可以使用计时器来检查所需的时间是否已过。但是。
    我建议您保持适合您要求的螺纹方式。
    或者,如果您想让工具API添加代码。我当然是在开玩笑:别那么做!

        2
  •  2
  •   user10639668 user10639668    6 年前

    Object#wait() Java doc

    线程也可以在不被通知、中断或删除的情况下唤醒 超时,所谓的虚假唤醒。但这种情况很少发生 如果条件不满足,则继续等待。 换句话说,, 等待应该总是在循环中发生

     synchronized (obj) {
         while (<condition does not hold>)
             obj.wait(timeout);
         ... // Perform action appropriate to condition
     }
    

    while (wait) {
      monitor.wait(config.getWaitTime());
    }
    

    这个 wait

        3
  •  1
  •   talex    6 年前