为什么Thread.sleep使用不好

Ran*_*ion 28 java multithreading java-threads

对这个重复的问题道歉,但我还没有找到任何令人满意的答案.大多数问题都有自己的特定用例:
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");
}
Run Code Online (Sandbox Code Playgroud)

我理解通过使用Thread.sleep块当前线程,从而消耗资源.但是在一个相当中等规模的应用程序中,一个主题是一个大问题吗?
我在那里阅读使用ScheduledThreadPoolExecutor并在那里进行轮询的状态.但同样,我们必须使用至少一个线程初始化此池,其中运行可执行轮询的runnable方法.

有关使用原因的任何建议都Thread.sleep被认为是一个糟糕的主意,以及实现上述目标的替代方案有哪些.

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

Enn*_*oji 35

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

在这种情况下,AFAIK您没有选项但是轮询,因为API没有为您提供通知.我也可以看到这是一个不经常的操作,因为大概你不会创建千表.

因此,我觉得Thread.sleep在这里使用很好.如你所说,当你要阻止当前线程时产生一个单独的线程似乎使事情变得复杂而没有任何价值.

  • 一个重要的警告:确保睡眠线程不会占用稀缺资源,如互斥锁或数据库连接. (9认同)

Ama*_*eep 9

是的,应该尽量避免使用Thread.sleep(x),但不应该完全忘记:

为什么要避免它

  • 它不释放锁
  • 它并不保证执行将在睡眠时间后开始(所以它可能会一直等待 - 显然是罕见的情况)
  • 如果我们错误地将前台处理线程置于休眠状态,那么我们将无法关闭该应用程序直到x毫秒.
  • 我们现在已满载特定问题的新并发包(如设计模式(当然不完全正确),为什么要使用Thread.sleep(x).

在哪里使用Thread.sleep(x):

  • 用于在后台运行线程中提供延迟
  • 还有其他人.

  • 你能解释几个吗?顺便说一句好答案。 (2认同)