Java 共享异常实例是否安全

Java 共享异常实例是否安全,java,exception,exception-handling,Java,Exception,Exception Handling,我们正在制作一个类似Excel的系统。当我们打开一个文档并发现不支持的函数时,我们抛出了异常。我们只支持excel函数的一小部分,这可能经常发生。问题是,当有很多单元格包含不受支持的函数时,就会创建大量的异常实例。创建这些异常实例需要耗费大量的时间 我们在exception类中没有任何特殊属性。我们需要知道的是异常被抛出的事实。我们刚刚发现发生了错误,并将单元格标记为错误 所以我们决定共享一个异常实例,并在需要时抛出它。异常实例可以由多个线程引发。我怀疑堆栈跟踪可能已损坏,但是,我们没有看到它。

我们正在制作一个类似Excel的系统。当我们打开一个文档并发现不支持的函数时,我们抛出了异常。我们只支持excel函数的一小部分,这可能经常发生。问题是,当有很多单元格包含不受支持的函数时,就会创建大量的异常实例。创建这些异常实例需要耗费大量的时间

我们在exception类中没有任何特殊属性。我们需要知道的是异常被抛出的事实。我们刚刚发现发生了错误,并将单元格标记为错误

所以我们决定共享一个异常实例,并在需要时抛出它。异常实例可以由多个线程引发。我怀疑堆栈跟踪可能已损坏,但是,我们没有看到它。我们只是捕获异常,并将相应的单元格标记为错误

我的问题是: 在这种情况下,共享异常实例是否安全? 嗯,我读了以下文章: 但情况似乎有所不同

感谢您提前阅读这一冗长的问题和回答

[…]共享异常实例是否安全?

是的,如果你小心的话

如果你不小心的话,这个例子可能会搞砸。确保每个线程都有自己的异常对象,或者重写
getStackTrace
并返回一个空数组

(JVM实际上在某些情况下重用异常实例。如果内存不足,它将重用预分配的
OutOfMemoryError
,而不是尝试创建一个新的异常实例。在这种情况下,
getStackTrace
返回一个空数组。)

相关问题:

我怀疑堆栈跟踪可能已损坏

它不会被破坏

但是,由于堆栈跟踪是在创建异常实例时捕获的,因此如果重用异常,堆栈跟踪将不正确。类似地,没有API方法在创建异常后更改异常的消息字符串,因此“共享”异常将始终具有相同的消息


这具有过早优化和/或在“非异常”控制流中使用异常的“味道”。最好的方法是每次抛出时只创建一个新的异常实例,只有在出现明确(实际)性能问题时才进行异常共享

更新-显然这不是过早的优化。然而,事实上,您的分析表明,您在创建异常实例方面花费了大量的时间,所以我建议您至少考虑包括减少抛出异常频率的可选优化。
我必须重写getStackTrace()以返回一个空数组


不可以。更好的方法是重写
fillInStackTrace()
方法以不捕获一个。在Java 7中,也有一种干净的方法可以使用
异常
构造函数参数来实现这一点。

谢谢。我必须重写getStackTrace()以返回一个空数组。谢谢您的详细解释。事实上,我们使用visualvm分析了应用程序,发现创建异常实例耗费了大量时间。我们希望使用Java7,但是由于某些原因,我们不能使用它。无论如何,非常感谢你。我最好在我的异常类中重写fillInStackTrace()方法。