Thread.sleep() 保证等待吗?
is Thread.sleep() guaranteed to wait?
考虑这种情况:
我想连续调用几个 Web 服务。我只能每 10 秒打一次电话。我有这样的东西:
while(true) //we will break inside the loop eventually
{
//...
try {
Thread.sleep(10000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
//make web service call here
//...
}
如您所见,这将(希望)大约每 10 秒调用一次。但我担心的是,当 Thread.sleep()
正在执行时,我会在 10 秒之前被打断,随后我将进行一个将被忽略的 Web 服务调用。
这不是一个多线程应用程序,因此它 运行 在自己的 JVM 上。这是唯一一个我没有从任何地方在这个线程上调用 interrupt()
的线程,但我不确定我是否 运行 会因为我的主机的线程调度程序或任何东西而陷入麻烦。
计时的准确性并不重要。我特别不在乎 10 秒是否变成 15 秒。但是,如果 Thread.Sleep
抛出得太早,我就会有麻烦了。
这是实现此行为的正确方法吗?
澄清一下:
1- 这不是多线程程序
2- 我不想做一个准确的时间,时间可能不准确 只要意外异常不会让我过早地退出 try 块
不,不能保证至少等待 10 秒。 sleep 方法抛出检查异常 InterruptedException 的要点 可能需要通过中断线程在 10 秒结束之前结束睡眠。
你错误地关注你的程序是 "single threaded"。实际上并没有这样的事情:JVM 和 JRE 被允许(事实上)运行 额外的线程。 Thread.sleep()
API 表示如果休眠线程被另一个线程中断,该方法将抛出 InterruptedException
;它没有指定只允许 "user" 个线程中断休眠线程。
I am not sure if I will run into trouble with my host machine's thread scheduler
不,运行时不会出于任何原因中断应用程序线程。只有应用程序中的其他代码(或使用您选择的某些框架拖入的代码)才会中断线程。
每个任务都应该指定一个中断策略:如果线程被中断会发生什么?应用程序不应该在不了解其中断策略并准备好处理后果的情况下中断线程。
因此,为您的线程定义中断策略。在您的应用程序中,这是您不希望发生的事情,如果有人向您的应用程序添加代码以在您的线程上调用 interrupt()
,他们就会引入错误。基本上,您的政策是不允许中断。因此,抛出一些未经检查的异常,如 IllegalStateException
是一个有效的响应。
Is this the proper way of implementing this behaviour?
不,不是。当您被打扰时,您应该向呼叫者发出您被打扰的信号。这应该通过让 InterruptedException
传播回调用者(或具有类似含义的 application-defined 异常)或通过恢复当前线程的中断状态来完成。假设您的中断策略通过提前终止循环来允许中断。您仍然应该恢复中断状态:
while(true) {
...
try {
Thread.sleep(10000);
} catch(InterruptedException abort) {
Thread.currentThread().interrupt();
break;
}
/* Make web service call here... */
}
考虑这种情况: 我想连续调用几个 Web 服务。我只能每 10 秒打一次电话。我有这样的东西:
while(true) //we will break inside the loop eventually
{
//...
try {
Thread.sleep(10000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
//make web service call here
//...
}
如您所见,这将(希望)大约每 10 秒调用一次。但我担心的是,当 Thread.sleep()
正在执行时,我会在 10 秒之前被打断,随后我将进行一个将被忽略的 Web 服务调用。
这不是一个多线程应用程序,因此它 运行 在自己的 JVM 上。这是唯一一个我没有从任何地方在这个线程上调用 interrupt()
的线程,但我不确定我是否 运行 会因为我的主机的线程调度程序或任何东西而陷入麻烦。
计时的准确性并不重要。我特别不在乎 10 秒是否变成 15 秒。但是,如果 Thread.Sleep
抛出得太早,我就会有麻烦了。
这是实现此行为的正确方法吗?
澄清一下:
1- 这不是多线程程序
2- 我不想做一个准确的时间,时间可能不准确 只要意外异常不会让我过早地退出 try 块
不,不能保证至少等待 10 秒。 sleep 方法抛出检查异常 InterruptedException 的要点 可能需要通过中断线程在 10 秒结束之前结束睡眠。
你错误地关注你的程序是 "single threaded"。实际上并没有这样的事情:JVM 和 JRE 被允许(事实上)运行 额外的线程。 Thread.sleep()
API 表示如果休眠线程被另一个线程中断,该方法将抛出 InterruptedException
;它没有指定只允许 "user" 个线程中断休眠线程。
I am not sure if I will run into trouble with my host machine's thread scheduler
不,运行时不会出于任何原因中断应用程序线程。只有应用程序中的其他代码(或使用您选择的某些框架拖入的代码)才会中断线程。
每个任务都应该指定一个中断策略:如果线程被中断会发生什么?应用程序不应该在不了解其中断策略并准备好处理后果的情况下中断线程。
因此,为您的线程定义中断策略。在您的应用程序中,这是您不希望发生的事情,如果有人向您的应用程序添加代码以在您的线程上调用 interrupt()
,他们就会引入错误。基本上,您的政策是不允许中断。因此,抛出一些未经检查的异常,如 IllegalStateException
是一个有效的响应。
Is this the proper way of implementing this behaviour?
不,不是。当您被打扰时,您应该向呼叫者发出您被打扰的信号。这应该通过让 InterruptedException
传播回调用者(或具有类似含义的 application-defined 异常)或通过恢复当前线程的中断状态来完成。假设您的中断策略通过提前终止循环来允许中断。您仍然应该恢复中断状态:
while(true) {
...
try {
Thread.sleep(10000);
} catch(InterruptedException abort) {
Thread.currentThread().interrupt();
break;
}
/* Make web service call here... */
}