java 线程中断:它会取消即将到来的 wait() 调用吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6698977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:57:20  来源:igfitidea点击:

Thread interrupt: will it cancel oncoming wait() call?

javamultithreadingconcurrencywait

提问by NagyI

I have a thread which has an incoming job queue (a LinkedListcontaining job descriptions). The thread blocks with wait()on the queue when there's no job to work on. An external job dispatcher object awakes it with notify()when it places new jobs on the queue.

我有一个线程,它有一个传入的作业队列(LinkedList包含作业描述)。wait()当没有工作要做时,线程阻塞在队列中。外部作业调度程序对象notify()在将新作业放入队列时唤醒它。

At shutdown of my program i call interrupt()on the Thread. This raises InterruptedExceptionwhen the Thread awaits for jobs in wait(). My question is: what will happen if i interrupt the Thread while it's not blocking but doing some kind of work, the processed item was the last in the queue (so queue is now empty) and execution pasts the isInterrupted()check before the interrupted flag is set so it calls wait()again? Will it throw an InterruptedExceptionbecause the interrupted flag has already been set or the thread waits forever because new jobs will never arrive to the queue and there's no one to interrupt the wait?

在我的程序关闭时,我调用interrupt()了线程。这就提出了InterruptedException对工作的线程将等待的时候wait()。我的问题是:如果我在线程没有阻塞但在做某种工作时中断它会发生什么,处理的项目是队列中的最后一个(所以队列现在是空的)并且isInterrupted()在设置中断标志之前执行通过检查所以它wait()再次调用?它会抛出一个InterruptedException因为中断标志已经设置或线程永远等待因为新作业永远不会到达队列并且没有人中断等待?

采纳答案by jtahlborn

yes, your interrupted thread will throw an InterruptedException upon calling wait(). this is pretty simple to test for yourself.

是的,您的中断线程将在调用 wait() 时抛出 InterruptedException。这对自己进行测试非常简单。

public class TestInt {
    public static void main(String[] args) throws Exception
    {
        Thread.currentThread().interrupt();

        synchronized(TestInt.class) {
            TestInt.class.wait();
        }    
    }    
}

also, note the javaodc for Object.wait():

另外,请注意 javaodc 的Object.wait()

InterruptedException - if any thread interrupted the current thread beforeor while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

InterruptedException - 如果在当前线程等待通知之前或期间任何线程中断了当前线程。抛出此异常时清除当前线程的中断状态。

回答by mre

Read the API specifications for Thread.interrupt()-

阅读 API 规范Thread.interrupt()-

Interrupts this thread.

Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.

If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.

Interrupting a thread that is not alive need not have any effect.

中断此线程。

除非当前线程正在中断自己,这总是被允许的,否则调用此线程的 checkAccess 方法,这可能会导致抛出 SecurityException。

如果此线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法或 join()、join(long)、join(long, int) 方法时被阻塞、 sleep(long) 或 sleep(long, int) 等方法,则其中断状态将被清除,并会收到 InterruptedException。

如果此线程在可中断通道上的 I/O 操作中被阻塞,则通道将关闭,线程的中断状态将被设置,线程将收到 ClosedByInterruptException。

如果该线程在 Selector 中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用了选择器的唤醒方法一样。

如果前面的条件都不成立,则将设置此线程的中断状态。

中断一个不活跃的线程不需要有任何影响。

So, all that will happen is the thread's interrupt status will be set.

所以,所有将发生的是线程的中断状态将被设置。

EDIT

编辑

If you read the API specifications for Object.wait(), you'll see the following -

如果您阅读 的 API 规范Object.wait(),您将看到以下内容 -

Throws:

InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

抛出:

InterruptedException -如果在当前线程等待通知之前或期间任何线程中断了当前线程。抛出此异常时清除当前线程的中断状态。