4

我正在阅读 Threads 的 sleep() 方法。我试图开发一个小例子。关于这个例子,我有两个困惑。

/**
 * Created with IntelliJ IDEA.
 * User: Ben
 * Date: 8/7/13
 * Time: 2:48 PM
 * To change this template use File | Settings | File Templates.
 */

class SleepRunnable implements Runnable{

  public void run() {
    for(int i =0 ; i < 100 ; i++){
      System.out.println("Running: " + Thread.currentThread().getName());
    }
    try {
      Thread.sleep(500);
    }
    catch(InterruptedException e) {
      System.out.println(Thread.currentThread().getName() +" I have been interrupted");
    }
  }
}

public class ThreadSleepTest {
  public static void main(String[] args){
    Runnable runnable = new SleepRunnable();
    Thread t1 = new Thread(runnable);
    Thread t2 = new Thread(runnable);
    Thread t3 = new Thread(runnable);
    t1.setName("Ben");
    t2.setName("Rish");
    t3.setName("Mom");
    t1.start();
    t2.start();
    t3.start();
  }
}
  1. 正如我在上一篇文章中所讨论的,如果线程在指定的时间后唤醒,则会发生中断异常,并且它将简单地从 run 方法返回。在我的这个例子中,代码永远不会进入 catch() 块。为什么会这样?
  2. 现在,上面示例中的所有线程都将休眠一秒钟并优雅地轮流,如果我特别想让线程“Ben”休眠怎么办。我不认为在这个例子中是可能的。

有人可以进一步详细说明这个概念。

4

4 回答 4

6

1.当达到 timout 时,不会抛出InterruptedException 。当您中断当前正在休眠的线程时,它会被抛出。

当线程等待、休眠或以其他方式被占用,并且线程在活动之前或期间被中断时抛出。有时某个方法可能希望测试当前线程是否已被中断,如果是,则立即抛出此异常。下面的代码可以用来实现这个效果: if (Thread.interrupted()) // 清除中断状态!抛出新的中断异常();

2.执行代码只能让当前线程休眠。因此,您可以按名称确定您的线程,例如:

if ("Ben".equals(Thread.currentThread().getName())) { 
try {
  Thread.sleep(500);
} catch (InterruptedException e) {}
}
于 2013-08-07T11:01:31.263 回答
4

正如我在上一篇文章中所讨论的,如果线程在指定的时间后唤醒,则会发生中断异常,并且它将简单地从 run 方法返回。在我的这个例子中,代码永远不会进入 catch() 块。为什么会这样?

您没有interrupt()在代码中的任何地方调用。

t1.interrupt(); //this will throw the exception when t1 is sleeping

现在,上面示例中的所有线程都将休眠一秒钟并优雅地轮流,如果我特别想让线程“Ben”休眠怎么办。我不认为在这个例子中是可能的。

准确地说,在这个例子中线程没有轮流,它们在不知道彼此的情况下单独工作。

提示: 检查当前线程的名字,如果名字是Ben.

Thread.currentThread().getName() //for getting the name of the current thread

编辑:

再现中断:将睡眠间隔增加到 10000 毫秒

主要方法代码:

Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
Thread t3 = new Thread(runnable);
t1.setName("Ben");
t2.setName("Rish");
t3.setName("Mom");
t1.start();
t2.start();
t3.start();

Thread.sleep(1000); //make the main thread to sleep for a sec

//time to interrupt t1 !!!!
t1.interrupt();   //throws Interrupted exception in the run method of Thread t1
于 2013-08-07T11:05:03.793 回答
2

1) 不正确,如果线程在指定超时后唤醒,则不会发生 InterruptedException,线程将简单地恢复运行。您的代码没有进入 catch 块,因为它从未被中断过,试试这个

...
t3.start();
t3.interrupt();
...

如果你想从 t3 查看 InterruptedException。

2)我认为你可以做这样的事情

...
if (Thread.currentThread().getName().equals("Ben")) {
    try {
      Thread.sleep(500);
    }
    ...

}
于 2013-08-07T11:01:30.157 回答
0

仅当运行时必须唤醒进程时才会发生 InterruptedException。通过 sleep() 使线程进入睡眠状态会使其脱离处理器的线程队列。如果它出于某种原因需要它的注意,那么它会触发一个 InterruptedException InterruptedException 也可能发生,同时它正在运行并且处理器必须在它的时间片用完之前从线程中夺走控制权,主要是因为有更高优先级的任务渴望得到关注。至少,这是我记得的!:)

于 2013-08-07T11:01:48.337 回答