2

期間ジョブが同時に複数回実行されるのを防ぐために、「ロック ファイル」を実装する Java クラスを作成しました。それは基づいてjava.nio.channels.FileChannel.tryLockおり、非常にうまく機能します。

私のクラスでは、クライアント コードで、ロック ファイルが使用可能になるまで待機する時間を示すタイムアウト値を指定できます。タイムアウトが発生した場合は、IOException. これも非常にうまく機能します。

しかし、かなり一般的であるため、使用するより良い例外タイプがあるかどうか疑問に思っています。IOExceptionをキャッチするクライアントコード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 を呼び出しているメソッドは、作成者が想定している意味でのブロッキング操作です。

あなたは言う:「これは実際には「同時」使用法ではありません...しかし、それはあなたの見方に依存します。APIを使用してLockおり、そのインターフェイスはjava.util.concurrentパッケージ ツリー内で宣言されています。また、並列アプリケーションで簡単に使用できるように API を設計していると思われます。(もしそうでなければ...どうしてですか?)


IMO、またはの既存またはカスタムのサブクラスを使用するための唯一の適切な議論は、クライアント操作がI/O操作としてモデル化されている場合です。たとえば、API が I/O 例外を使用して他のことを知らせる場合です。IOExceptionIOException

使用に反対するもう 1 つのIOException理由は、一般的すぎるということです。APIメソッドの呼び出し元には、 「準備が必要です」 IOException書かれています。これには、現在の実装ではスローされないが、将来の実装ではスローされる可能性があるあらゆる種類の例外が含まれます。


もう 1 つの方法は、 のサブクラスではない独自のカスタム例外クラスを宣言することですIOException。一見すると、これは I/O 例外よりも優れているように見えます。


「実装の詳細」の問題に関しては、クラスはロック メカニズムとしてディスク上のファイルを使用するように設計され、文書化されています。したがって、それは間違いなく実装の詳細ですが、実装、インターフェイスなどの定義であるため、少なくとも IOException は不適切ではないと思います。

そのような API を指定するのは悪い考えだと私は主張します。後で、別の種類のロックの方が適切であると判断したとします。インターフェイスでロックの詳細を指定した場合、それらを変更することはできません。または、少なくとも、API の既存のクライアントを壊す可能性のある方法で「コントラクトを書き直す」ことなくではありません。

于 2016-12-10T00:42:25.540 に答える
1

IOException を拡張するカスタム例外クラスを作成します。これにより、クライアントは、必要に応じて特定の例外を処理するか、失敗する可能性のある他のすべての理由とともに汎用 IOException として処理できます。

簡単に実装できます。発信者が使いやすい。

于 2016-12-09T22:36:13.157 に答える