什么时候调用Thread.currentThread().interrupt()以及什么时候不调用? [英] When to call Thread.currentThread().interrupt() and when not to call?

查看:1522
本文介绍了什么时候调用Thread.currentThread().interrupt()以及什么时候不调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在互联网上的多篇文章中,建议不要吞下InterruptedException.当我要重用相同的线程时,使用这样的线程池执行程序来执行此操作更有意义.

From multiple articles around the internet it's advised not to swallow InterruptedException. It makes much more sense to do it with thread pool executors something like this when I'm going to reuse the same thread.

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 .

但是在每次创建新线程的情况下,

But in the case of creating new thread each time like:

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();吗?这有意义吗?

Do I still need to call Thread.currentThread().interrupt();? Will that make any sense?

好的参考文献:

https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-多线程/

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

推荐答案

我将根据出色的书

I will give an answer based on section 7.1.2 of great book Concurrency in Practice by Brian Goetz.

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

In your first example you use ExecutorService. ExecutorService manages it's own threads. You are not the owner of those Threads so you do not know what interruption means to them ( for example ThreadPool might choose to kill Threads that were interrupted and create new ones). That is why you should preserve interruption status when you submit a cancelable task to this pool. This citation applies to this case:

任务不会在其拥有的线程中执行,而是借用诸如线程池之类的服务拥有的线程.编码 不拥有线程(对于线程池,线程池实现之外的任何代码)都应谨慎 保留中断状态,以便拥有代码最终可以对它执行操作,即使来宾"代码对已执行操作起作用 以及打扰. (如果您要为某人提供住房,则不要丢掉他们不在时收到的邮件-保存并让他们回来后再处理,即使您确实阅读了他们的杂志也是如此.)

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 的实例.因此,您是它的所有者.因此,您可以确定对该线程 意味着什么中断,并且如果不想应用任何 Thread中断,则不必保留第二种情况下的 Interruption Status .政策:

In the second case you manage an instance of Thread manually. So you are the owner of it. Therfore you decide what interruption means to this Thread and you do not have to preserve the Interruption Status in the second case if you do not want to apply any Thread Interruption Policy for it :

您不应该做的就是吞下InterruptedException并在catch块中不执行任何操作,除非您的代码实际上为线程实现了中断策略

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

还请注意,线程中断策略任务取消策略不同:

  1. 线程中断策略-定义线程对中断的反应(例如,ThreadPool可能会杀死被中断的线程并创建一个新线程).它由线程的所有者定义.
  2. 任务取消策略-定义任务对取消的反应.取消通常是在中断的情况下执行的.执行任务的人选择是否响应中断的任务.如果您的任务调用抛出InterruptedException的方法,则可以轻松实现这一点.或者,您可以通过调用Thread::isInterrupted(例如在循环中)检查线程的中断标志.任务的实施者选择处理方式.
  1. Thread Interruption Policy - defines how Thread reacts to interruption (for example ThreadPool might kill Thread that was interrupted and create a new one). It is defined by the owner of the thread.
  2. Task Cancellation Policy - defines how task reacts to cancellation. Cancellation is usually implemented with interruption. The one who implements the task chooses if task in responsive to interruption. This is easily achieved if your task calls methods that throw InterruptedException. Or you can check the interruption flag of the Thread by calling Thread::isInterrupted (for example in a loop). The implementor of the task chooses how to handle this.

此外,您也不应假设线程中断策略(如果您不是Thread的所有者).这就是为什么保留中断状态或重新抛出InterruptedException被认为是一种好习惯的原因.

Also you should not take any assumptions of Thread Interruption Policy (if you are not the owner of the Thread). That is why preserving Interruption Status or rethrowing InterruptedException is considered a good practice.

这篇关于什么时候调用Thread.currentThread().interrupt()以及什么时候不调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆