据我所知,Java的Exception类肯定不是不可变的(像initCause
和setStackTrace
这样的方法提供了一些线索)。它至少是线程安全的吗?假设我的一个类有这样一个字段:
private final Exception myException;
我可以安全地将此字段公开给多个线程吗? 我不愿意讨论具体情况,以及为什么会出现这种情况。我的问题更多的是关于这个原则:我可以告诉一个暴露Exception类型字段的类是线程安全的吗?
另一个例子:
class CustomException extends Exception
{
...
}
这个类是否是线程安全的?
答案 0 :(得分:7)
请注意initCause()
为synchronized
,setStackTrace()
复制其参数,然后进行单一作业。
所以Exception
实际上似乎是在考虑线程安全的情况下实现的。尽管如此,我还是要警惕线程之间常例传递异常的任何设计(即除了处理非常严重的错误条件之外的任何原因)。这只是感觉不对。
答案 1 :(得分:1)
对于sun的java 6执行throwable
initCause
是synchronized
所以它是线程安全的。
fillInStackTrace
也是。
setStackTrace
不,但它会对输入进行防御性复制,然后分配该副本。当然,该方法是“用于rpc框架”。
只要您的myException字段为final或volatile,就可以共享。
答案 2 :(得分:1)
我相信安全地发布Throwables / Exceptions是一个非常有效的问题。 DJClayworth的评论是“如果您在线程之间共享异常实例,那么您将其用于未设计的目的”并不考虑使用Futures的任务管理代码。工作线程通常会抛出异常,并且该异常需要由不同的线程处理。除了上面提到Throwable的同步方法的所有注释之外,Future还发布了线程之间的异常,因此我相信可以肯定地说这是预期的,安全的和支持的功能。
答案 3 :(得分:0)
我不相信Java Exception类提供任何线程安全保证。
答案 4 :(得分:-1)
检测到条件时会抛出异常的目的,并在处理条件时捕获它。根据定义,这些应该在单个线程内发生。如果您在线程之间共享一个Exception实例,那么您将其用于未设计的目的。这样做会让您的读者感到困惑,并使您的程序难以维护。您可能应该考虑使用它的替代结构。