43

为这个重复的问题道歉,但我还没有找到任何令人满意的答案。大多数问题都有自己的特定用例:
Java - 替代 thread.sleep
有没有更好或替代的方法来跳过/避免在 Java 中使用 Thread.sleep(1000)?

我的问题是针对非常通用的用例。等待条件完成。做一些操作。检查一个条件。如果条件不成立,等待一段时间再做同样的操作。

例如,考虑一种通过调用其 createAPI 表来创建 DynamoDB 表的方法。DynamoDB 表需要一些时间才能变为活动状态,因此该方法将调用其 DescribeTable API 以定期轮询状态,直到某个时间(假设 5 分钟 - 由于线程调度导致的偏差是可以接受的)。如果表在 5 分钟内变为活动状态,则返回 true,否则抛出异常。

这是伪代码:

public void createDynamoDBTable(String name) {
  //call create table API to initiate table creation

  //wait for table to become active
  long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE;

  while(System.currentTimeMillis() < endTime) {
    boolean status =  //call DescribeTable API to get status;
    if(status) {
         //status is now true, return
         return
    } else {
        try {
            Thread.sleep(10*1000);
        } catch(InterruptedException e) {
        }
    }
  }

  throw new RuntimeException("Table still not created");
}

我知道通过使用Thread.sleep阻塞当前线程,从而消耗资源。但是在一个中等规模的应用程序中,一个线程是一个大问题吗?
我在某处阅读ScheduledThreadPoolExecutor并在那里进行状态轮询。但同样,我们必须用至少 1 个线程来初始化这个池,在该线程中运行可运行的方法来进行轮询。

关于为什么使用的任何建议Thread.sleep都被认为是一个坏主意,以及实现上述相同的替代选择是什么。

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-design-program.aspx

4

2 回答 2

51

在这种情况下使用很好Thread.sleep。人们不鼓励的原因Thread.sleep是因为它经常用于修复竞争条件的不良尝试,用于基于通知的同步是更好的选择等。

在这种情况下,AFAIK 您别无选择,只能轮询,因为 API 不向您提供通知。我还可以看到这是一个不常见的操作,因为大概您不会创建数千个表。

因此,我觉得在这里使用它很好Thread.sleep。正如您所说,无论如何,当您要阻塞当前线程时产生一个单独的线程似乎会使事情复杂化而没有任何价值。

于 2013-07-24T06:44:25.323 回答
15

Yes, one should try to avoid usage of Thread.sleep(x) but it shouldn't be totally forgotten:

Why it should be avoided

  • It doesn't release the lock
  • It doesn't gurantee that the execution will start after sleeping time (So it may keep waiting forever - obviously a rare case)
  • If we mistakenly put a foreground processing thread on sleep then we wouldn't be able to close that application till x milliseconds.
  • We now full loaded with new concurrency package for specific problems (like design patterns (ofcourse not exactly), why to use Thread.sleep(x) then.

Where to use Thread.sleep(x):

  • For providing delays in background running threads
  • And few others.
于 2017-03-15T17:11:26.640 回答