单个Thread.interrupt()中断多次

时间:2015-12-18 12:07:38

标签: java multithreading interrupt

我创建了MyTaskrun()内有3件事要做。我尝试interrupt()保存MyTask实例的线程。不幸的是,一旦它被中断,它就会结束,只有字符串First task被打印在控制台上。

public class MyTask implements Runnable {
    private volatile Thread thread;

    @Override
    public void run() {
        while (!thread.isInterrupted()) {
            System.out.println("First task");
        }
        while (!thread.isInterrupted()) {
            System.out.println("Second task");
        }
        while (!thread.isInterrupted()) {
            System.out.println("Third task");
        }
    }

    public Thread start(){
        thread = new Thread(this);
        thread.start();
        return thread;
    }


    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyTask().start();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
        Thread.sleep(1000);
        t.interrupt();
    }

}

如果我在Thread.sleep(10)中添加run(),则正常工作,并打印First taskSecond task,最后{{1}在控制台上。

问题是:仅当我添加Third task时,Whydoes Thread.interrupts()才能正常工作?

sleep()

2 个答案:

答案 0 :(得分:4)

引用Interrupts

  

当线程通过调用静态方法Thread.interrupted检查中断时,中断状态被清除。非静态isInterrupted方法,一个线程用来查询另一个线程的中断状态,不会改变中断状态标志。

含义:将代码从thread.isInterrupted()更改为Thread.interrupted(),然后重试。

你的循环之间的sleep()将立即清除该标志(立即抛出InterruptedException(因为当前的线程已被中断)

答案 1 :(得分:0)

查看Thread.sleep(long)

上的Javadoc
  

抛出:InterruptedException - 如果有任何线程中断了当前线程。 抛出此异常时,将清除当前线程的中断状态

因此,添加sleep以及捕获(并加入)任何异常都将导致观察到的行为。

示例:

没有sleep()

  • 线程以interrupted = false开头,因此第一个循环运行
  • 线程被中断,即现在interrupted = true
  • 第一次循环检查interrupted并且不再运行(再次)
  • 第二次循环检查interrupted并且不会全部运行
  • 第3次循环检查interrupted并且不会全部运行
  • 成品

使用sleep()

  1. 主题以interrupted = false
  2. 开头
  3. 循环1:

    • 同时检查条件并从interrupted = false
    • 执行正文
    • 线程被中断,即现在interrupted = true
    • 虽然检查了条件但是这次interrupted = true所以循环结束
    • 调用
    • sleep(),因为线程已被中断,所以抛出异常并再次interrupted = false
    • 异常被捕获(并被忽略),因此正常继续执行
  4. 对循环2和3重复步骤2

  5. 成品