清除Thread.interrupt()标志的方法 [英] Methods that Clear the Thread.interrupt() flag

查看:186
本文介绍了清除Thread.interrupt()标志的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近继承了一个大型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屋!

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