Java 为什么使用Thread.sleep不好
我为这个重复的问题道歉,但我还没有找到任何令人满意的答案。大多数问题都有自己的特定用例:Java 为什么使用Thread.sleep不好,java,multithreading,java-threads,Java,Multithreading,Java Threads,我为这个重复的问题道歉,但我还没有找到任何令人满意的答案。大多数问题都有自己的特定用例: 我的问题是关于非常通用的用例。等待条件完成。做些手术。检查情况。如果条件不正确,请等待一段时间,然后再次执行相同的操作 例如,考虑通过调用CurATIAPI表创建一个DyDoDB表的方法。DynamoDB表需要一些时间才能变为活动状态,所以方法将调用其可描述的API,以定期轮询状态,直到某个时间(假设5分钟-由于线程调度而产生的偏差是可以接受的)。如果表在5分钟内变为活动状态,则返回true,否则引发异
我的问题是关于非常通用的用例。等待条件完成。做些手术。检查情况。如果条件不正确,请等待一段时间,然后再次执行相同的操作
例如,考虑通过调用CurATIAPI表创建一个DyDoDB表的方法。DynamoDB表需要一些时间才能变为活动状态,所以方法将调用其可描述的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");
}
public void createDynamoDBTable(字符串名称){
//调用CREATETABLeAPI以启动表创建
//等待表变为活动状态
long endTime=System.currentTimeMillis()+MAX\u WAIT\u TIME\u FOR\u TABLE\u CREATE;
while(System.currentTimeMillis()
我知道通过使用Thread.sleep
阻塞当前线程,从而消耗资源。但是在中等规模的应用程序中,一个线程是一个大问题吗?我在某个地方读到了使用
ScheduledThreadPoolExecutor
并在那里进行状态轮询的内容。但同样,我们必须用至少一个线程初始化这个池,在这个线程中,执行轮询的runnable方法将运行
任何关于为什么使用Thread.sleep
的建议都被认为是一个糟糕的主意,以及实现上述目标的其他选择是什么
在这种情况下,可以使用
线程。睡眠。人们不鼓励Thread.sleep
的原因是它经常被用于修复竞争条件的错误尝试中,在基于通知的同步是更好的选择等情况下使用
在这种情况下,AFAIK您没有选择权,只能进行轮询,因为API不向您提供通知。我还可以看出,这是一个不常见的操作,因为您大概不会创建上千个表
因此,我发现在这里使用Thread.sleep
很好。正如您所说,在您要阻止当前线程时生成一个单独的线程似乎会使事情变得复杂而没有价值。是的,应该尽量避免使用线程。睡眠(x),但不应该完全忘记:
为什么应该避免
- 它不会释放锁
- 它不能保证执行将在睡眠时间后开始(因此它可能会永远等待-显然这是一种罕见的情况)
- 如果我们错误地将前台处理线程置于睡眠状态,那么直到x毫秒我们才能关闭该应用程序
- 我们现在已经为特定问题(比如设计模式(当然不完全是),以及为什么要使用Thread.sleep(x))加载了新的并发包
在何处使用线程。睡眠(x):
- 用于在后台运行线程中提供延迟
- 其他的也很少
你的链接是关于.Net的。它不适用于Java。毫无疑问,轮询是不好的。但如果你没有其他选择,这是你最不应该关心的事情。@StinePike,这是否意味着,答案在博客中?我看过这篇文章,但除了资源阻塞(已经提到)之外,没有看到任何特别的东西这个线程需要每n毫秒执行一次逻辑,正如前面提到的,睡眠意味着放弃控制。当你的线程再次获得控制权时,它不符合线程的要求;因此它不能用于周期性逻辑。
但我想,他说的是在n毫秒之后进行调度。投票认为“太广泛”的人请告诉我我怎样才能使它更具体?我已经问了很多关于这个方法的用例的问题。一个大的警告:确保睡眠线程没有占用稀缺的资源,比如互斥或数据库连接。这种模式在以下情况下也可以接受吗?-一次轮询一条消息的SQS并维护消息列表ges。当列表的大小达到X个数字时,批量处理它们。如果SQS中没有更多消息,请休眠一段时间。然后再次轮询。@Jitendra:通常使用MQs时,您希望避免轮询,但恐怕除了在SQS中轮询之外,没有其他方法(即使没有消息,他们也会收取费用),所以Thread.sleep
是一个选项。不过我可能倾向于使用scheduled executor,因为它可以轻松添加使用者、微调轮询的调度并强制您分离业务逻辑和基础结构。您能解释其他几个吗?顺便说一句,答案很好。