线程中断。有人能解释一下输出以更好地理解中断吗?

时间:2015-04-25 11:51:18

标签: java multithreading interrupt interrupted-exception

我能够理解线程和中断。我试图将从Oracle教程中学到的基本概念映射到更好地理解中断的概念。我开发了这个例子并努力理解输出,因为中断在这里起作用。我只是不明白。所以我的想法是请某人帮助我理解这个程序的输出,这将使我更清楚地了解中断的基本功能。

public class ThreadSleepTest {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable myRunnable = new MyRunnable();
        Thread one = new Thread(myRunnable);
        one.setName("Fred");
        Thread two = new Thread(myRunnable);
        two.setName("Lucy");
        Thread three = new Thread(myRunnable);
        three.setName("Ricky");
        one.start();
        two.start();
        three.start();
        //Thread.sleep(1000);
        one.interrupt();
     }    
}

class MyRunnable implements Runnable {
    public void run() {
        for (int x = 1; x < 4; x++) {
            System.out.println("Run by: " + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                System.out.println("Exception occured");
            }
        }
        System.out.println("Do something");
    }
}

这是我的控制台的输出。

Run by: Lucy
Run by: Fred
Run by: Ricky
Exception occured
Run by: Fred
Run by: Fred
Run by: Lucy
Run by: Ricky
Do something
Run by: Lucy
Run by: Ricky
Do something
Do something

4 个答案:

答案 0 :(得分:1)

中断线程意味着要求它停止执行当前的操作。

当运行的线程被中断并且在该线程中引发InterruptedException时,大多数I / O和锁定操作将中断(但是,并非所有操作都这样做,例如参见https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquireUninterruptibly()

然后代码能够以他/她认为合适的任何方式处理异常。引发InterruptedException后,中断信号被消耗,线程可以继续执行任何操作。在您的示例中,Thread.sleep()调用之前完成,将抛出InterruptedException并记录消息。之后,线程继续for循环。当然,线程可以稍后中断。

答案 1 :(得分:1)

  

一旦线程中断,根据我的理解,它基本上就会被取消。

不,你的理解是不正确的。一旦线程被中断,由编写run方法的程序员决定如何处理它。

线程终止完全取决于程序员,因为JVM实际上并不知道在终止线程时可能需要清理哪些资源和锁。这就是为什么stop()中的方法suspend()Thread已被弃用的原因。他们不安全。

因此,当一个线程被中断时,如果你在一个抛出InterruptedException的方法中,你必须对这个异常作出反应并完成你正在做的任何事情,如果你在你的中间你自己的东西,你必须不时检查当前线程的interrupted()状态,如果发生中断,完成你正在做的事情。

以下是线程中断时您选择执行的操作:

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) {
            System.out.println("Exception occured");
        }

catch子句中,您只是打印出发生异常的事实。你实际上没有做任何事情来终止线程。因此,它不会被终止。您将退出catch子句,并继续循环的下一次迭代。

按惯例

Thread.sleep()在抛出InterruptedException时清除中断的标志。因此,在下一次迭代中,线程不再被#34;中断&#34;,sleep()不会再次抛出异常。

答案 2 :(得分:1)

我认为Java Concurrency in Practice(JCiP),第138页给出了可能发生的事情的相当好的解释。您可以注意到以下几点:

  • 主线程创建并启动3个名为Fred,Lucy,Ricky的线程。我们只考虑名为Fred的线程,它被赋值给变量one(有更好的方法可以做到这一点,例如CountdownLatch)。
  • Fred计划运行后立即通过您的代码进入睡眠状态。方法Thread.sleep是精心设计的阻止调用。这意味着它可以通过发送中断来中断。这正是主线程试图做的事情:请求线程one正在做或不做的任何活动中断(因为它只是在这种情况下睡觉)。 main线程只需在interrupt()上调用one方法即可完成此操作。请注意,这仅被视为一个友好的请求&#39;由线程中断。
  • 如果您看到输出&#39;异常发生&#39;,(休眠)中断的线程确认中断,并且如同记录一样,则抛出InterruptedException。 one捕获此异常,并发出消息&#39;异常发生&#39;在stdout上印有。因此,主线程成功地中断了one正在做的事情
  • 其他线程不间断地执行任务(这就是您查看其他打印语句的原因)。

答案 3 :(得分:0)

如果你打断一个线程,那么你在这个线程中睡觉或等待的下一个或当前时间会抛出一个InterruptedException。但是用这个清除了中断状态。如果您的线程被中断,您应该在不久的将来终止它。