- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我偶然发现了一种情况,我必须处理 InterruptedException
,但无法将其向上传递并且不认为我的代码应该被允许吞下它。准确地说,我正在研究分布式锁实现,并且对支持服务的请求可能会中断甚至超时 - 当然,java.util.concurrent.Lock
不考虑对于这种情况,不允许我吐出 InterruptedException。我正在努力为非抛出 lock()
、tryLock()
和 unlock()
方法编写正确的实现。
那么,问题是 - 处理这种情况的正确策略是什么?从目前的角度来看,我只看到三个选项(我觉得每个选项都有味道):
lock
/tryLock
/unlock
方法中的中断异常,重试/返回 false/假设即使请求没有到达它的目的地,TTL 最终将解锁记录。这显然不是最好的解决方案,因为它希望一切都好,而不是处理问题。RuntimeException
继承人中。这似乎也是一个糟糕的解决方案,因为客户端代码必须使用具体的实现而不是原始接口(interface),而且未经检查的异常肯定不是为了那样的目的。Thread.currentThread().interrupt()
调用。我不喜欢这种方式,因为它基本上告诉线程处理它自己的中断,而不是传递有关调用被中断的通知;另外,据我所知,如果没有外部轮询,它最终会产生线程,但不会立即处理中断,可能在完全不同的地方。(当然,有一个选项允许客户端代码配置所需的行为,但这仍然没有为我提供一个真正好的解决方案)
有没有比我描述的更好的方法?如果不是,应该优先选择哪一个?
最佳答案
让我讨论一下您的每一个可用选项。
- Ignore interrupted exception
这是错误的。当您实现其他用户将依赖的库之类的东西时,吞下异常永远是不对的。在这些情况下,吞下一个异常永远不会是明智的,除非你将它作为一个不同的异常传播,为客户端提供更有意义的信息。 InterruptedException
基本上是一个取消线程的请求,无论稍后是否解锁锁,都不应从客户端抑制此信息。客户端需要知道有人希望停止此线程正在执行的工作单元。
- Wrap in
RuntimeException
没有。由于与上述完全相同的原因,这也是错误的。传播 InterruptedException
的原因是让客户端知道已发出取消执行线程的请求,因此将其包装在 RuntimeException
中是错误的,因为此信息是丢失的。
- Use/force
Thread.currentThread().interrupt()
call
这可能是正确的,也可能是错误的,具体取决于用例。问问自己是否可以传播 InterruptedException。
如果这样做没问题(这不是你的情况,但是),那么你可以声明你的方法抛出 InterruptedException
并让上面的调用者担心需要做什么完毕。当您调用抛出 InterruptedException
的方法(比如 operation()
)并且您将无法继续进行时,通常会出现这种情况,除非这个调用完成。假设 operation()
抛出 InterruptedException
,那么除了传播此异常之外,您无能为力。所以你不应该捕获这个异常(exception)。在这种情况下,只需声明您的方法抛出 InterruptedException
即可完成
如果不能这样做,那么正确的处理方法是强制调用 interrupt()
。使用它可以抑制异常,但您仍然可以让客户端选择检查标志以查看是否发出了中断请求。你是对的。这需要客户端轮询而不是处理中断。但这并没有错。如果您不希望客户端进行轮询,那么传播异常将是更好的选择。但这并不总是可能的,您的示例就是这样一个用例。并且在很多情况下,执行线程即使在被中断时也可以返回一些有意义的信息。所以在这种情况下,异常被抑制了,但是仍然可以通过调用 interrupt()
方法传递存在终止请求的信息。因此,客户端可以只使用从部分计算返回的结果,也可以轮询以检查是否根据用例设置了中断标志。因此,您通过这样做为客户提供了更大的灵 active 。
关于java - 如何正确处理可能未传递给客户端代码的 InterruptedException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36808407/
场景如下。 我实现了一个这样的界面: public interface MessageSourceProvider { MessageSource getMessageSource(Local
这个问题已经有答案了: I want my thread to handle interruption, but I can't catch InterruptedException because
这段代码应该可以编译,不是吗?我究竟做错了什么?我希望代码在显示数组中的每个数字之前短暂暂停。 public static void median(int odd[]) throws Interrup
我正在学习 Java 并发,并尝试了 Java 教程中的示例,并进行了一些实验( try catch 异常)。 public class SleepMessages { public stat
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Handling InterruptedException in Java 我想知道如何InterruptedExc
这个问题已经有答案了: Handling InterruptedException in Java (7 个回答) 已关闭 6 年前。 我有课 class Foo { static void
我有两个同步适配器,我希望每个同步适配器都等到另一个同步适配器完成后再开始执行。我对信号量使用了以下技术: public class SyncerOne extends AbstractThreade
Given code is working in doInBackground(). Where while loop is always true but i don't know how it c
我有一个以 LinkedBlockingQueue 作为属性的类 A。在 A 的一种方法中,我调用了 LinkedBlockingQueue.put() 方法,因为我想在队列中插入一个项目。但是,如果
我对 Java SE 6 中 Condition 类的 await 方法有一个奇怪的问题。问题是 await 方法在被另一个线程中断时并不总是抛出异常。 在文档中写到在以下情况下会抛出 IE: ...
我很困惑,无法理解为什么不应该吞下 InterruptedException。 IBM 的文章说 当阻塞方法检测到中断并抛出 InterruptedException 时,它会清除中断状态。如果您捕捉
我正在阅读 kathy sierra SCJP 1.5 第 9 章(线程),其中提到: Notice that the sleep() method can throw a checked Inter
我一直在同步块(synchronized block)内收到此异常,在同步块(synchronized block)中我对同步的同一个对象调用等待。一个线程首先被中断是什么意思?其次,发生这种情况的正
对于任何 Java 大师来说,这应该是一个简单的练习。我是新手,只是想确认一件事。 我有一个实现 Runnable 的类,与许多此类类一样,它的 run() 方法有一个无限循环。我想做一些任务,然后睡
我有以下方法,效果很好。我正在尝试测试抛出 InterruptedException 的场景。这就是我目前正在测试的方式,如果我只运行这个单一测试,它会起作用。但是如果我要在我的测试类中运行所有剩余的
我偶然发现了一种情况,我必须处理 InterruptedException,但无法将其向上传递并且不认为我的代码应该被允许吞下它。准确地说,我正在研究分布式锁实现,并且对支持服务的请求可能会中断甚至超
我正在尝试编写一个程序,其中每个类都有单独的类和方法,交叉调用其他类的方法。下面是我想从另一个类的另一个方法调用的编码方法。 public class walk{ public void wa
我有一个 vaadin 应用程序,它使用 hibernate 并在 glassfish 中上传,我们收到此错误: AdmissionWeb:2018-07-03 12:01:06 [WARN ][ht
我有代码,需要等待一段时间作为繁忙等待的一部分(由于遗留代码,我无法更改那么多)。我已经阅读了为什么我应该在此处执行此操作的推理 [1] 和 [2],并且它是显而易见的经验法则。经常这样做。 IIUC
我有这段代码。如果在等待添加到队列时被中断,LinkedBlockingQueue 应该仅抛出 Exception。但这个队列是无限的,所以它应该尽快添加。为什么我的关闭方法会抛出 Interrupt
我是一名优秀的程序员,十分优秀!