清除Thread.interrupt()标志的方法 [英] Methods that Clear the Thread.interrupt() flag
问题描述
我最近继承了一个大型Java应用程序,其中几乎没有线程安全性.我目前正在做的是让所有线程正确处理被中断的情况,而不是使用非常糟糕的Thread.stop()
.
I have recently inherited a large Java Application that has almost no Thread safety in it. What I'm currently working on is getting all of the Threads to correctly handle being interrupted instead of using the very bad Thread.stop()
.
部分问题是,我不知道在那里清除中断标志的每个方法调用.
Part of the problem has been that I do not know every method call out there that clears the interrupt flag.
目前,我知道以下内容将清除中断标志:
Currently I know that the following will clear the interrupt flag:
Thread.interrupted()
Thread.sleep(long)
Thread.join()
Thread.join(long)
Object.wait()
Object.wait(long)
我还想念什么?谢谢
推荐答案
部分问题是,我不知道在那里清除中断标志的每个方法调用.
Part of the problem has been that I do not know every method call out there that clears the interrupt flag.
重要的是要澄清以下方法仅通过调用它们来清除中断标志:
It is important to clarify that the following methods clear the interrupt flag by just calling them:
Thread.interrupted()
Thread.isInterrupted(true) -- added to your list
因此,应始终使用Thread.currentThread().isInterrupted()
代替.
For this reason Thread.currentThread().isInterrupted()
should always be used instead.
以下方法将通过立即抛出InterruptedException
来清除中断的标志,如果调用了它们,然后线程被中断了,或者,如果线程是已经被打断,然后被调用(请参见下面的junit代码).因此,不是清除标志而是抛出异常的方法.
The following methods will clear the interrupted flag by immediately throwing InterruptedException
either if they were called and then the thread was interrupted or if the thread was already interrupted and then they were called (see junit code below). So it is not the method that clears the flag, throwing the exception does.
您的初始列表:
Thread.interrupted()
Thread.sleep(long)
Thread.join()
Thread.join(long)
Object.wait()
Object.wait(long)
已添加到您的列表中:
Thread.sleep(long, int)
Thread.join(int, long)
Thread.isInterrupted(true)
Object.wait(int, long)
BlockingQueue.put(...)
BlockingQueue.offer(...)
BlockingQueue.take(...)
BlockingQueue.poll(...)
Future.get(...)
Process.waitFor()
ExecutorService.invokeAll(...)
ExecutorService.invokeAny(...)
ExecutorService.awaitTermination(...)
CompletionService.poll(...)
CompletionService.take(...)
CountDownLatch.await(...)
CyclicBarrier.await(...)
Semaphore.acquire(...)
Semaphore.tryAcquire(...)
Lock.lockInteruptibly()
Lock.tryLock(...)
请注意,使用 any 代码捕获InterruptedException
的正确模式是立即重新中断线程.我们这样做是为了防止其他人依赖thread.isInterrupted()
方法:
Please note that the proper pattern with any code that catches InterruptedException
is to immediately re-interrupt the thread. We do this in case others are relying on the thread.isInterrupted()
method:
try {
...
} catch (InterruptedException e) {
// immediately re-interrupt the thread
Thread.currentThread().interrupt();
// log the exception or [likely] quit the thread
}
JUnit代码演示了其中的一些内容:
JUnit code that demonstrates some of this:
assertFalse(Thread.currentThread().isInterrupted());
// you can do this from another thread by saying: someThread.interrupt();
Thread.currentThread().interrupt();
// this method does _not_ clear the interrupt flag
assertTrue(Thread.currentThread().isInterrupted());
// but this one _does_ and should probably not be used
assertTrue(Thread.interrupted());
assertFalse(Thread.currentThread().isInterrupted());
Thread.currentThread().interrupt();
assertTrue(Thread.currentThread().isInterrupted());
try {
// this throws immediately because the thread is _already_ interrupted
Thread.sleep(1);
fail("will never get here");
} catch (InterruptedException e) {
// and when the InterruptedException is throw, it clears the interrupt
assertFalse(Thread.currentThread().isInterrupted());
// we should re-interrupt the thread so other code can use interrupt status
Thread.currentThread().interrupt();
}
assertTrue(Thread.currentThread().isInterrupted());
这篇关于清除Thread.interrupt()标志的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!