2

我编写了一个实现“锁定文件”的 Java 类,以防止一个周期作业同时运行多次。它基于java.nio.channels.FileChannel.tryLock并且运行良好。

我的类允许客户端代码提供一个超时值,指示它愿意等待锁定文件可用多长时间,如果发生超时,我将抛出一个IOException. 这也很有效。

但我想知道是否有更好的异常类型可以使用,因为IOException它相当通用。捕获 an 的客户端代码IOException将无法知道问题是由于例如超时本身还是文件系统的其他问题等(IOException当然,除非其他问题引发子类)。

简要浏览 Java API,我看到了一些候选者,但出于各种原因,我并不真正喜欢它们中的任何一个:

  1. java.util.concurrent.TimeoutException(这不是真正的“并发”用法)
  2. java.nio.channels.FileLockInterruptionException(文档指出了此异常的一个非常具体的原因;与我的情况不符)
  3. java.nio.channels.InterruptedByTimeoutException(与上述类似的原因)

有什么建议么?

如果可能的话,我更喜欢 Java 7 可用的东西。

编辑

显然,自定义异常类是可能的,但我想知道标准 API 中是否有合适的东西。

4

3 回答 3

2

我认为这java.util.concurrent.TimeoutException是合适的。javadoc 说:

“阻塞操作超时时抛出异常。指定超时的阻塞操作需要一种方法来指示已发生超时。”

从作者设想的意义上讲,您调用 trylock 的方法是一种阻塞操作。

您说:“这不是真正的“并发”用法”……但这取决于您的观点。您正在使用LockAPI,并且该接口在java.util.concurrent包树中声明。并且大概您正在设计您的 API,以便它可以轻松地在并发应用程序中使用。(如果不是……为什么不呢?)


IMO,使用或现有或自定义子类的唯一论据是客户端操作是否被建模为 I/O 操作。例如,如果 API 使用 I/O 异常来发出其他信号。IOExceptionIOException

反对使用的另一个论点IOException是它太笼统了。它说您的 API 方法的调用者“您需要为任何 IOException做好准备。这包括您当前的实现不会抛出的各种异常,但未来可能会抛出。


另一种选择是声明您自己的自定义异常类,它不是IOException. 从表面上看,这似乎比 I/O 异常要好。


至于“实现细节”问题,该类被设计和记录为使用磁盘文件作为锁定机制。所以虽然它绝对是一个实现细节,但它是实现、接口等的定义,所以我认为 IOException 至少不是不合适的。

我认为指定这样的 API 是个坏主意。假设您稍后决定另一种锁定可能更合适。如果您在界面中指定了锁定详细信息,则无法更改它们。或者至少,如果没有以可能破坏 API 现有客户端的方式“重写合同”,则并非如此。

于 2016-12-10T00:42:25.540 回答
1

创建一个扩展 IOException 的自定义异常类。这允许客户端在需要时处理特定异常,或者作为通用 IOException 以及可能失败的所有其他原因。

便于您实施。方便来电者使用。

于 2016-12-09T22:36:13.157 回答
0

JDK 包含许多超时异常的变体,例如SQLTimeoutExceptionSocketTimeoutException等,但不幸的是,没有TimeoutException可以扩展或普遍用于所有超时异常的父类。

所以,你可以编写一个自定义的 Exception 并使用它,如下所示:

public class FileTimeoutException extends IOException {

    private String message;

     public FileTimeoutException(String message) {
           this.message= message;
     }
    //add the other required methods
}
于 2016-12-09T22:54:10.953 回答