繁体   English   中英

共享异常实例是否安全

[英]Is it safe to share exception instance

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

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

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

我的问题是:在这种情况下,共享异常实例是否安全? 好吧,我看了下面的文章: Java:Exception类是线程安全的吗? 但背景似乎有所不同。

感谢您提前阅读这个长期问题和回复。

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

是的,如果你小心的话。

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

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

相关问题:

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

它不会被破坏。

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


这具有过早优化的“气味”和/或在“非特殊”控制流程中使用例外。 最好的方法是在每次throw时简单地创建一个新的异常实例,如果你有明确的(真正的)性能问题,那么只会乱用异常。

更新 - 显然这不是一个不成熟的优化。 但是,您的分析显示您在创建异常实例时花费了大量时间这一事实,我建议您至少考虑降低抛出异常频率的替代优化。


好吧,我必须覆盖getStackTrace()以返回一个空数组。

不是。更好的想法是覆盖fillInStackTrace()方法以不捕获一个。 在Java 7中还有一种使用Exception构造函数参数执行此操作的简洁方法。

暂无
暂无

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

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