首页 文章

while循环中的Thread.sleep()

提问于
浏览
20

我注意到NetBeans警告我在我的Java代码中使用while循环中的Thread.sleep(),所以我已经对这个主题进行了一些研究 . 主要问题似乎是性能问题,当计数器仍处于休眠状态时,你的状态可能会变为真,因此在等待下一次迭代时会浪费挂钟时间 . 这一切都很有道理 .

我的应用程序需要联系远程系统并定期轮询操作状态,等待操作完成后再发送下一个请求 . 目前,代码在逻辑上执行此操作:

String state = get state via RPC call
while (!state.equals("complete")) {
    Thread.sleep(10000); // Wait 10 seconds
    state = {update state via RPC call}
}

鉴于情况是检查远程操作(这是一个有点昂贵的过程,因为它运行了几秒钟),这是一个在while循环中有效使用Thread.sleep()吗?有没有更好的方法来构建这个逻辑?我已经看到了一些我可以使用Timer类的例子,但是我没有看到它的好处,因为它似乎仍然归结为上面相同的直接逻辑,但是引入了更多的复杂性 .

请记住,在这种情况下,远程系统既不是我的直接控制,也不是用Java编写的,因此在这种情况下将此端更改为“合作”不是一种选择 . 我更新应用程序状态值的唯一选择是创建和发送XML消息,接收响应,解析它,然后提取我需要的信息 .

任何建议或意见都是最受欢迎的 .

3 回答

  • 12

    除非您的远程系统可以发出事件或以其他方式异步通知您,否则我认为上述情况完全不合理 . 你需要 balancer 你的 sleep() 时间与RPC调用所做的时间/负载,但我认为's the only issue and the above doesn' t似乎完全没有问题 .

  • 4

    无法更改远程端以提供“推送”通知,即通过其长时间运行的流程完成,这与您将能够做的一样 . 只要Thread.sleep时间比轮询成本长,你应该没问题 .

  • 0

    你应该(几乎)从不使用睡眠,因为它非常低效,而且不是一个好习惯 . 始终使用锁和条件变量,其中线程相互发出信号 . 见Mike Dahlin的Coding Standards for Programming with threads

    模板是:

    public class Foo{
      private Lock lock;
      private Condition c1;
      private Condition c2;
    
      public Foo()
      {
        lock = new SimpleLock();
        c1 = lock.newCondition();
        c2 = lock.newCondition();
        ...
      }
    
      public void doIt()
      {
        try{
          lock.lock();
          ...
          while(...){
            c1.awaitUninterruptibly();
          }
          ...
          c2.signal();
        }
        finally{
          lock.unlock();
        }
      }
    }
    

相关问题