为什么Thread.sleep不好用

问题描述 投票:0回答:2

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

我的问题是针对非常通用的用例。等待条件完成。做一些操作。检查是否有条件。如果条件不成立,请等待一段时间,然后再次执行相同的操作。

例如考虑一种通过调用 DynamoDB 表的 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-Designed-program.aspx

java multithreading java-threads
2个回答
53
投票

在这种情况下使用

Thread.sleep
就可以了。人们不鼓励
Thread.sleep
的原因是因为它经常用于修复竞争条件的不良尝试,用于基于通知的同步是更好的选择等。

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

因此,我觉得这里用

Thread.sleep
就可以了。正如您所说,当您要阻止当前线程时生成一个单独的线程似乎会使事情变得复杂而没有优点。


17
投票

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

为什么应该避免

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

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

  • 用于在后台运行线程中提供延迟
  • 还有其他一些。
© www.soinside.com 2019 - 2024. All rights reserved.