java - 什么时候调用 Thread.currentThread().interrupt() 什么时候不调用?

标签 java multithreading interrupt

从互联网上的多篇文章中建议不要吞下InterruptedException .当我要重用同一个线程时,使用线程池执行程序来做这样的事情更有意义。

public static void main(String[] args) throws InterruptedException {

    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<?> future = executor.submit(() -> {
        printNumbers(); // first call
        printNumbers(); // second call
    });
    Thread.sleep(3_000);                                     
    executor.shutdownNow();  // will interrupt the task
    executor.awaitTermination(3, TimeUnit.SECONDS);
}

private static void printNumbers() {
    for (int i = 0; i < 10; i++) {
        System.out.print(i);
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // preserve interruption status
            break;
        }
    }
}

以上代码示例来自 DZone .

但是在每次创建新线程的情况下,例如:
Object LOCK = new Object();

public void doSomeJob() {

    myThread = new Thread(new Runnable() {
        public void run() {
            try {
               synchronized(LOCK) {
               System.out.println("Inside run");
               LOCK.wait();
              }
            } catch(InterruptedException ignored){}
        }
    }
}

我还需要打电话Thread.currentThread().interrupt();吗? ?这有什么意义吗?

很好的引用:

https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/

http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html

最佳答案

我将根据 部分给出答案7.1.2 好书Concurrency in Practice通过布赖恩·戈茨。

在您的第一个示例中,您使用 ExecutorService . ExecutorService管理它自己的线程。您不是这些线程的所有者,因此您不知道中断对它们意味着什么(例如 ThreadPool 可能会选择杀死被中断的线程并创建新线程)。这就是为什么在向此池提交可取消任务时应保留中断状态的原因。此引文适用于这种情况:

Tasks do not execute in threads they own.They borrow threads owned by a service such as a thread pool. Code that doesn't own the thread (for a thread pool, any code outside of the thread pool implementation) should be careful to preserve the interrupted status so that the owning code can eventually act on it, even if the "guest" code acts on the interruption as well. (If you are housesitting for someone, you don't throw out the mail that comes while they're away - you save it and let them deal with it when they get back, even if you do read their magazines.)



在第二种情况下,您手动管理 Thread 的实例。所以你是它的所有者。因此,您决定中断对该线程意味着什么,并且如果您不想为其应用任何线程中断策略,则不必在第二种情况下保留中断状态:

What you should not do is swallow the InterruptedException by catching it and doing nothing in the catch block, unless your code is actually implementing the interruption policy for a thread



另请注意,线程中断策略与任务取消策略不同:
  • 线程中断策略 - 定义线程对中断的 react (例如 ThreadPool 可能会杀死被中断的线程并创建一个新线程)。它由线程的所有者定义。
  • 任务取消策略 - 定义任务对取消的 react 。取消通常是通过中断来实现的。执行任务的人选择是否响应中断任务。如果您的任务调用抛出 InterruptedException 的方法,这很容易实现。 .或者你可以通过调用Thread::isInterrupted来查看线程的中断标志。 (例如在循环中)。任务的实现者选择如何处理这个问题。

  • 此外,您不应该对线程中断策略进行任何假设(如果您不是 Thread 的所有者)。这就是为什么要保留中断状态或重新抛出 InterruptedException被认为是一种很好的做法。

    关于java - 什么时候调用 Thread.currentThread().interrupt() 什么时候不调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57575457/

    相关文章:

    java - 用于暂停操作的信号量,不限制并发操作

    java - 将图像数据从 Java 传递到 C native 函数接受指针

    JavaFX 一对多(1 :n) In TableView

    multithreading - 在OMP(gfortran)中使用原子的奇怪结果

    Java:SourceDataLine.write(...) 屏蔽中断吗?

    java - 使用 Jbutton 停止线程 (Java)

    arduino - 我无法清除 Arduino Uno 中的外部中断

    Java Web 解析器带有 cookies?

    java - 如何检测测试是否在 GitLab CI 服务器上运行

    c# - 从可以重新添加对象的阻塞集合中消费