Java - 线程问题

时间:2010-05-03 07:15:31

标签: java multithreading sleep

我的问题与投掷Thread.sleep(...)的所有方法(包括InterruptedException)有关。

我发现有关Sun的教程的声明

  

InterruptedException是一个异常,sleep在另一个线程在睡眠处于活动状态时中断当前线程时抛出。

这是否意味着如果在中断时sleep未激活,将忽略中断?

假设我有两个主题:threadOnethreadTwothreadOne创建并启动threadTwothreadTwo执行runnable,其run方法类似于:

public void run() {
    :
    :
    try {
        Thread.sleep(10 * 1000);
    } catch (InterruptedException e) {
        return;
    }
    :
    :
    : // In the middle of two sleep invocations
    :
    :
    try {
        Thread.sleep(10 * 1000);
    } catch (InterruptedException e) {
        return;
    }
    :
    :
}

创建线程后,threadOne会中断threadTwo。假设threadTwo在中断时(当没有睡眠方法处于活动状态时)处于两次睡眠调用的中间,那么第二次睡眠方法会在调用后立即抛出InterrupteException吗? p>

如果没有,那么这个中断会永远被忽略吗?

如何确保threadTwo始终知道中断(无论其中一种睡眠方法是否有效)都无关紧要?

4 个答案:

答案 0 :(得分:3)

来自javadoc:

  

如果此线程被阻止   调用wait(),wait(long),   或等待(long,int)方法   对象类,或者join(),   join(long),join(long,int),   睡觉(长),或睡觉(长,int),   这个类的方法,然后它的   中断状态将被清除   它会收到一个   InterruptedException的。

     

如果此线程在I / O中被阻止   对可中断的操作   然后通道将是通道   关闭,线程的中断状态   将被设置,线程将   收到ClosedByInterruptException。

     

如果此线程被阻止   然后选择线程的中断   状态将被设置,它将返回   立即从选择   操作,可能是非零   值,就像选择器一样   唤醒唤醒方法。

     

如果没有以前的条件   然后保持这个线程的中断   状态将被设置。

这意味着您必须检查中断状态以确保您的线程知道中断。这可以通过两种方法完成:isInterrupted()和interrupted()。最后一个清除了中断状态。

这样的事情:

while(!Thread.interrupted()) {
  ...
  try {
    Thread.sleep(10 * 1000);
  } catch (InterruptedException e) {
    return;
  }
}

答案 1 :(得分:2)

在Sun的Windows JDK上,线程实际上会在输入InterruptedException时抛出sleep()

public static final void main(String args[]) throws Exception {
    final Thread main = Thread.currentThread();
    Thread t = new Thread() {
        @Override
        public void run() {
            main.interrupt();
        }
    };
    t.start();
    t.join();
    Thread.sleep(1000);
    System.out.println("Not interrupted!");
}

sleep()的API文档可以解释为这是强制性行为:

  

抛出InterruptedException - 如果有的话   线程已中断当前   线。中断的状态   当前线程被清除   抛出异常。

但这不是很清楚,所以我不会依赖它,而是手动检查isInterrupted()

答案 2 :(得分:2)

Java文档有点误导。如果设置了线程的中断状态,则在该线程上调用sleep()将导致立即抛出InterruptException

即使线程在调用 sleep()之前被中断,这也适用。

如上所述,您也可以查看Thread.isInterrupted()是否要自行处理中断。

答案 3 :(得分:-1)

InterruptionException仅在线程休眠期间感兴趣。如果线程在之前的任何地方被中断,则后面的sleep()调用不会抛出它。只有sleep()时的中断才有意义,因为它会完全打破sleep()调用。