As I understand, Java's Exception class is certainly not immutable (methods like initCause
and setStackTrace
give some clues about that). So is it at least thread-safe? Suppose one of my classes has a field like this:
private final Exception myException;
Can I safely expose this field to multiple thr开发者_高级运维eads? I'm not willing to discuss concrete cases where and why this situation could occur. My question is more about the principle: can I tell that a class which exposes field of Exception type is thread-safe?
Another example:
class CustomException extends Exception
{
...
}
Is this class thread-safe?
Note that initCause()
is synchronized
and setStackTrace()
copies its parameter and then does a single assignment.
So Exception
actually does seem to be implemented with thread-safety in mind. Still, I'd be wary of any design where exceptions are routinely passed around between threads (i.e. for any reason other than handling a very serious error condition). It just feels wrong.
I believe safely publishing Throwables/Exceptions is a perfectly valid question. DJClayworth's comment that "if you are sharing an instance of Exception between threads then you are using it for a purpose for which it was not designed" does not account for task management code with Futures. It is common for a worker-thread to throw an exception, and for that exception to need to be handled by a different thread. In addition to all the comments above that mention the synchronized methods of Throwable, Future publishes Exceptions between threads, thus I believe it's safe to say that this is expected, safe, and supported functionality.
For sun's java 6 implementation of throwable
initCause
is synchronized
so it's thread safe.
fillInStackTrace
is too.
setStackTrace
is not, but it makes a defensive copy of the input and then assigns that copy. Of course, that method is "for rpc frameworks".
As long as your myException field is final or volatile, it should be ok to share.
I do not believe that any guarantees of threadsafety are provided by the Java Exception classes.
The purpose of an Exception is to be thrown when the condition is detected and caught when it is handled. By definition these should happen within a single thread. If you are sharing an instance of Exception between threads then you are using it for a purpose for which it was not designed. Doing that will confuse your readers and make your program less maintainable. You should probably consider an alternative structure for whatever you are using it for.
精彩评论