Thread.sleep()保证等待吗?

时间:2016-01-21 19:31:45

标签: java multithreading jvm

考虑这种情况: 我想连续进行几次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块,时间可能不准确

2 个答案:

答案 0 :(得分:1)

  

我不确定我是否会遇到主机的线程调度程序

不,运行时不会因任何原因中断应用程序线程。只有您应用程序中的其他代码(或者您使用您选择的某个框架拖入的代码)才会中断线程。

每个任务都应该指定一个中断策略:如果线程中断会发生什么?应用程序不应该在不理解其中断策略的情况下中断线程并准备好处理后果。

因此,为您的线程定义中断策略。在您的应用程序中,这是您不希望发生的事情,如果有人向您的应用程序添加了在您的线程上调用interrupt()的代码,则会引入错误。基本上,您的政策是不允许中断。因此,抛出一些未经检查的异常,例如IllegalStateException是一个有效的响应。

  

这是实现此行为的正确方法吗?

不,不是。当你被打断时,你应该通知来电者你被打断了。这应该通过让InterruptedException传播回调用者(或具有类似含义的应用程序定义的异常),或者通过恢复当前线程上的中断状态来完成。假设您的中断策略允许中断,通过过早终止循环。您仍应恢复中断状态:

while(true) {
  ...
  try {
    Thread.sleep(10000);
  } catch(InterruptedException abort) {
    Thread.currentThread().interrupt();
    break;
  }
  /* Make web service call here... */
}

答案 1 :(得分:0)

不,不能保证等待至少10秒钟。 抛出已检查异常的sleep方法的全部 InterruptedException是可能需要通过中断线程在10秒之前结束睡眠。

你错误地关注你的程序是什么"单线程"。在实践中没有这样的事情:JVM和JRE被允许(实际上是)运行其他线程。 Thread.sleep() API表示如果休眠线程被另一个线程中断,则该方法抛出InterruptedException;它没有指定只有" user"允许线程中断休眠线程。