有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java单线程。interrupt()中断多次

我创建了MyTask,它在run()内有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();
    }

}

如果我在run()中添加Thread.sleep(10),它开始正常工作,并在控制台上打印First taskSecond task和最后Third task

问题是:为什么只有当我添加sleep()Thread.interrupts()才能正常工作

public class MyTask implements Runnable {
    private volatile Thread thread;

    @Override
    public void run() {
        while (!thread.isInterrupted()) {
            System.out.println("First task");
        }
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        while (!thread.isInterrupted()) {
            System.out.println("Second task");
        }
        try {
            Thread.sleep(10);
        } catch (Exception e) {
        }
        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();
    }

}

共 (2) 个答案

  1. # 1 楼答案

    请看一下Thread.sleep(long)上的Javadoc

    Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

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

    例如:

    没有sleep()

    • 线程以interrupted = false开始,因此第一个循环运行
    • 线程被中断,即现在interrupted = true
    • 第一个循环检查interrupted并且没有运行(再次)
    • 第二个循环检查interrupted并且根本不运行
    • 第三个循环检查interrupted并且根本不运行
    • 完成

    sleep()

    1. 线程以interrupted = false开头
    2. 循环1:

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

    4. 完成
  2. # 2 楼答案

    引自Interrupts

    When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.

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

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