【问题标题】:Noncancelable Task that Restores Interruption Before Exit在退出前恢复中断的不可取消任务
【发布时间】:2011-10-13 08:59:32
【问题描述】:

我正在阅读一些 java 线程中断,但我不明白一些东西。希望有人能给我解释一下。所以,它完成了下面的代码

public Integer getInteger(BlockingQueue<Integer> queue) {
    boolean interrupted = false;
    try {
        while (true) {
            try {
                return queue.take();
            } catch (InterruptedException e) {
                interrupted = true;
                // fall through and retry
            }
        }
    } finally {
        if (interrupted)
            Thread.currentThread().interrupt();
    }
}

解释如下:

不支持取消但仍调用的活动 可中断的阻塞方法必须循环调用它们, 检测到中断时重试。在这种情况下,他们应该保存 本地中断状态并在返回前恢复, 如清单所示。而不是在捕获后立即 中断异常。过早设置中断状态可能 导致无限循环,因为大多数可中断阻塞 方法检查进入时的中断状态并抛出 如果设置了 InterruptedException,则立即。 (可中断方法 通常在阻塞或执行任何重要操作之前轮询中断 工作,以便尽可能应对中断。)

我不明白为什么要在本地保存中断状态。
我很高兴听到一些解释。

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    根据设计,该方法永远不会抛出 InterruptedException。所以这意味着我们总是期望从队列中获取一个值。但是有人可能希望线程被中断,这就是为什么我们必须在我们最终从队列中获取一个值之后保存-恢复中断状态。

    所以,线程只有在从队列中取出一个值后才会结束。

    更新:查看take() 方法的实现。它具有以下作为第一条语句:

    public final void acquireInterruptibly(int arg) throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
    ...
    }
    

    【讨论】:

    • 好的,我知道有人可能会中断运行此方法的线程(并且该方法会破坏 IE),但为什么不在 catch 中调用“Thread.currentThread().interrupt()”阻止?
    • “大多数可中断的阻塞方法在进入时检查中断状态,如果设置了则立即抛出 InterruptedException”。这意味着如果您在 catch 块中设置它,它会在 take() 方法中再次循环,并且该方法可以在执行任何工作之前立即退出(因为您已设置中断状态)。
    • 好的,明白了,谢谢,最后一个问题,要到达finally块应该怎么做?
    • 一个 finally 块总是在退出 try 块时执行,不管是否有异常。
    • finally块会在方法返回之前执行,对吧?
    【解决方案2】:

    循环会因为语句而结束

    return queue.take(); 
    

    这不是一个紧密的循环,即使它看起来像一个。它只是阻塞一个元素,一旦可用就返回,如果发生中断则重试。

    【讨论】:

    • 只有当我们遇到某种未捕获的异常时,才能到达 finally 块?
    • 不,finally 块总是在退出 try 块时执行,无论是否有异常。
    • finally 块被总是执行 - 无论是否抛出异常 - 所以在上面的代码中,如果元素可用,该方法将执行 finally 块并立即返回。如果元素不可用,它会阻塞。如果在阻塞时抛出 InterruptedException,它只会为一个元素退出,但是最终,在 所有 情况下,finally 块将在方法返回之前执行。
    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2021-06-05
    • 1970-01-01
    相关资源
    最近更新 更多