7

Excelのようなシステムを作っています。ドキュメントを開いてサポートされていない関数を見つけたとき、例外をスローしました。私たちはExcel関数の小さなサブセットをサポートしているだけです。これは頻繁に発生する可能性があります。問題は、サポートされていない関数を含むセルがたくさんある場合、たくさんの例外インスタンスが作成されることです。そして、それらの多くの例外インスタンスを作成すると、無視できないほどの時間がかかります。

例外クラス内に特別なプロパティはありません。知っておく必要があるのは、例外がスローされるという事実です。エラーが発生したことがわかり、セルをエラーとしてマークします。

そこで、1つの例外インスタンスを共有し、必要に応じてそれをスローすることにしました。例外インスタンスは、複数のスレッドによってスローされる可能性があります。スタックトレースが破損している可能性がありますが、表示されません。例外をキャッチし、対応するセルをエラーとしてマークします。

私の質問は次のとおりです。この状況では、例外インスタンスを共有しても安全ですか? さて、私は次の記事を読みました: Java:例外クラスはスレッドセーフですか? しかし、文脈は異なっているようです。

この長い質問と回答を事前に読んでいただきありがとうございます。

4

2 に答える 2

6

[...]例外インスタンスを共有しても安全ですか?

はい、気をつければ。

注意しないと、getStackTraceたとえば、混乱する可能性があります。各スレッドに独自の例外オブジェクトがあることを確認するかgetStackTrace、空の配列をオーバーライドして返します。

(JVMは実際に例外インスタンスを再利用する場合があります。メモリが不足するとOutOfMemoryError、たとえば新しいインスタンスを作成する代わりに、事前に割り当てられたインスタンスを再利用します。この場合、getStackTraceは空の配列を返します。)

関連する質問:

于 2012-07-13T15:15:14.213 に答える
5

スタックトレースが破損している可能性があります。

破損することはありません。

ただし、例外インスタンスの作成時にスタックトレースがキャプチャされるため、例外を再利用すると、スタックトレースは正しくなりません。同様に、作成後に例外のメッセージ文字列を変更するAPIメソッドがないため、「共有」例外には常に同じメッセージが含まれます。


これには、時期尚早の最適化の「匂い」や、「非例外的な」制御フローでの例外の使用があります。最善のアプローチは、毎回新しい例外インスタンスを作成することthrowです。明確な(実際の)パフォーマンスの問題がある場合にのみ、例外の共有をいじりまわします。

更新-明らかにこれは時期尚早の最適化ではありません。ただし、プロファイリングで例外インスタンスの作成にかなりの時間を費やしていることが示されているため、少なくとも、例外をスローする頻度を減らすことを含む代替の最適化を検討することをお勧めします。


空の配列を返すには、getStackTrace()をオーバーライドする必要があります。

いいえ。メソッドをオーバーライドしてfillInStackTrace()キャプチャしないようにすることをお勧めします。Exceptionコンストラクター引数を使用してJava7でこれを行うクリーンな方法もあります。

于 2012-07-13T15:34:22.740 に答える