【问题标题】:Concurrent version of Queue needs exceptions队列的并发版本需要异常
【发布时间】:2011-10-29 00:59:19
【问题描述】:

我正在编写一个实现队列接口的自定义队列。此实现是线程安全的,并且在某些情况下会阻塞。

普通的队列接口没有提到异常,因此我不能在我的实现中抛出任何InterruptedException

我看到了这个问题的两种解决方案,但它们都不是很令人满意:

  1. 移除队列接口并抛出异常。这使得代码无法用于需要队列的外国软件。

  2. 抛出 RuntimeException,这将产生大量令人惊讶的软件活动,我不想冒险。

不知何故,像ArrayBlockingQueue 这样的实现设法实现了QueueBlockingQueue。这是要走的路吗,或者这里有什么诀窍?

【问题讨论】:

  • 如果您的代码需要抛出异常,那么您必须使用RuntimeException。如果没有,那么您将不得不从异常中恢复并重试或其他方式。我在这里看不到任何简单的答案。在InterruptedException的情况下,我通常只是做一个Thread.currentThread().interrupt()然后退出线程。
  • 您特别关注哪些方法?
  • 出于好奇,您介意分享您的用例吗,其中没有一个现有的并发集合适合您?
  • 我正在编写一个 BoundedBlockingQueue 以任何类型的队列作为参数。我只找到了一个 scala 实现,所以我正在编写一个 java 实现。我特别想提供一个在运行时更改边界的功能。
  • 供将来参考:ArrayBlockingQueue 始终是有界的,但容量不能在运行时更改。类似地,LinkedBlockingQueue 可能是有界的,但仍然不允许更改容量。我的直觉告诉我 LinkedBlockingQueue 将是修改以获得所需行为的良好候选者。

标签: java multithreading concurrency queue blockingqueue


【解决方案1】:

如果你正在实现一个Queue,它可能需要抛出一个InterruptedException,那么我猜你真的想实现一个BlockingQueue。如果您阅读此接口的 javadoc,您会意识到 Java 语言设计者基本上已经说过,在 BlockingQueue 的上下文中,正常的 Queue 操作要么立即成功,要么立即失败。如果add 方法不能成功,Queue 接口提供IllegalStateException,如果offer 方法失败,则返回falseBlockingQueue 接口引入了新方法puttake 以及offerpoll 的重载变体,用于可能阻塞并因此需要抛出InterruptedException 的操作。

【讨论】:

    【解决方案2】:

    你应该选择选项一。

    当人们想要拥有一个队列(接口)时,他们会期望队列以某种方式工作。行为在接口中指定,客户端在切换时无需担心实现或进行更改。

    您的队列并非如此,如果您实现此接口但抛出运行时异常,您将以意想不到的方式打破客户的期望。 国外的软件要求一个队列正是因为他们不想被“欺骗”得到不可互换的东西。

    最好通过不实现队列来明确这一点,除非您可以在对象中透明地处理中断的异常。

    【讨论】:

      猜你喜欢
      • 2015-05-07
      • 1970-01-01
      • 2022-11-09
      • 1970-01-01
      • 2017-06-16
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多