简体   繁体   English

I / O超时使用的最佳异常类型是什么?

[英]What is the best exception type to use for an I/O timeout?

I've written a Java class that implements a "lock file" to prevent a period job from running more than once concurrently. 我编写了一个Java类,该类实现了一个“锁定文件”,以防止定期作业并发运行多次。 It's based upon java.nio.channels.FileChannel.tryLock and works quite well. 它基于java.nio.channels.FileChannel.tryLock并且运行良好。

My class allows client code to supply a timeout value indicating how long it's willing to wait for the lock file to become available, and if a timeout occurs, I'm throwing an IOException . 我的类允许客户端代码提供一个超时值,该值指示等待锁文件变得可用的时间,如果发生超时,则抛出IOException This also works quite well. 这也很好。

But I'm wondering if there is a better exception type to be using, since IOException is fairly generic. 但是我想知道是否有更好的异常类型要使用,因为IOException是相当通用的。 Client code catching an IOException wouldn't be able to know if the problem was due to eg the timeout itself or some other issue with the filesystem, etc. (unless that other issue throws a subclass of IOException of course). 捕获IOException客户端代码将无法知道问题是否是由于超时本身或文​​件系统的其他问题等引起的(当然,除非其他问题引发了IOException的子类)。

Briefly leafing through the Java API, I see some candidates but I don't really like any of them for various reasons: 简要地翻阅Java API,我看到了一些候选人,但出于各种原因,我真的不喜欢其中的任何一个:

  1. java.util.concurrent.TimeoutException (this isn't really a "concurrent" usage) java.util.concurrent.TimeoutException (这实际上不是“并发”用法)
  2. java.nio.channels.FileLockInterruptionException (docs indicate a very specific reason for this exception; doesn't match my case) java.nio.channels.FileLockInterruptionException (文档指示此异常的非常具体的原因;与我的情况不符)
  3. java.nio.channels.InterruptedByTimeoutException (similar reasons to above) java.nio.channels.InterruptedByTimeoutException (与上述类似原因)

Any suggestions? 有什么建议么?

I'd prefer something that is available back to Java 7 if possible. 如果可能的话,我希望可以在Java 7中使用。

EDIT 编辑

Obviously, a custom exception class is possible, but I was wondering if there was something in the standard API that would be appropriate. 显然,可以使用自定义异常类,但是我想知道标准API中是否有合适的东西。

I think that java.util.concurrent.TimeoutException is appropriate. 我认为java.util.concurrent.TimeoutException是合适的。 The javadoc says: Javadoc说:

"Exception thrown when a blocking operation times out. Blocking operations for which a timeout is specified need a means to indicate that the timeout has occurred." “阻塞操作超时时引发异常。为其指定了超时的阻塞操作需要一种手段来指示发生了超时。”

Your method that is calling trylock is a blocking operation in the sense that is envisaged by the authors. 按照作者的设想,调用trylock的方法是一种阻塞操作。

You say: "this isn't really a "concurrent" usage" ... but that depends on your perspective. 您说:“这不是真正的“并发”用法”……但这取决于您的观点。 You are using a Lock API, and that interface is declared within the java.util.concurrent package tree. 您正在使用Lock API,并且在java.util.concurrent包树中声明了该接口。 And presumably you are designing your API so that it can easily be used in a concurrent application. 大概是在设计API,以便可以在并发应用程序中轻松使用它。 (And if not ... why not?) (如果没有...为什么不呢?)


IMO, the only good argument for using IOException or an existing or custom subclass of IOException would be if the client operation is modeled as an I/O operation. IMO,使用唯一的好争论IOException或现有的或自定义子类IOException ,如果客户端操作建模为I / O操作会。 For instance, if the API uses I/O exceptions to signal other things. 例如,如果API使用I / O异常来发出其他信号。

Another argument against using IOException is that it is too general. 反对使用IOException另一个论点是它太笼统了。 It says the the caller of your API method(s) "you need to be prepared for any IOException " . 它说您的API方法的调用者“您需要为任何 IOException做好准备” That includes all sorts of exceptions that your current implementation won't throw, but a future one might. 这包括您当前的实现不会抛出的各种异常,但将来可能会抛出。


The other alternative is to declare your own custom exception class that is not a subclass of IOException . 另一种选择是声明您自己的自定义异常类,它不是IOException的子类。 On the face of it, that appears better than an I/O exception. 从表面上看,这似乎比I / O异常要好。


As for the "implementation detail" issue, the class is designed and documented to use an on-disk file as a locking mechanism. 对于“实现细节”问题,该类经过设计和记录,可以使用磁盘上的文件作为锁定机制。 So while it definitely is an implementation detail, it's the definition of the implementation, interface, etc. so I think IOException is at least not inappropriate. 因此,尽管它绝对是实现细节,但它是实现,接口等的定义。因此,我认为IOException至少不是不适当的。

I would argue that it is a bad idea to specify an API like that. 我会认为指定这样的API是一个坏主意。 Suppose that you decide later on that another kind of locking might be more appropriate. 假设您稍后决定另一种锁定可能更合适。 If you have specified the locking details in the interface, you can't change them. 如果您在界面中指定了锁定详细信息,则无法更改它们。 Or at least, not without "rewriting the contract" in a way that could break an existing client of the API. 或至少,并非没有“重写合同”的方式,这可能会破坏现有的API客户端。

Create a custom exception class that extends IOException. 创建一个扩展IOException的自定义异常类。 This allows the client to either handle the specific exception if it wants to, or as a generic IOException along with all the other reasons that things might fail. 这允许客户端根据需要处理特定的异常,或者作为通用IOException以及可能导致故障的所有其他原因来处理。

Easy for you to implement. 易于实施。 Easy for the caller to use. 呼叫者易于使用。

JDK contains lots of variants of timeout Exceptions like SQLTimeoutException , SocketTimeoutException , etc.., but unfortunately, there is no parent class such as TimeoutException which can be extended or generally used across for all Timeout exceptions. JDK包含许多超时异常的变体,例如SQLTimeoutExceptionSocketTimeoutException等。但是,不幸的是,没有诸如TimeoutException类的父类可以扩展或通常用于所有Timeout异常。

So, you can write a custom Exception and use it, as shown below: 因此,您可以编写一个自定义Exception并使用它,如下所示:

public class FileTimeoutException extends IOException {

    private String message;

     public FileTimeoutException(String message) {
           this.message= message;
     }
    //add the other required methods
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM