views:

154

answers:

5

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 threads? 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?

A: 

I do not believe that any guarantees of threadsafety are provided by the Java Exception classes.

jsight
+5  A: 

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.

Michael Borgwardt
+1 for "just feels wrong."
Yishai
The first example is actually hypothetical. I can hardly imagine something like this in my code :)Regarding the second example. Can I say in my documentation that class CustomException is thread-safe, and sleep well after?
Vilius Normantas
@Vilius: do you have to satisfy some hare-brained requirement saying that all classes "must be thread-safe"? And of course, a thread-safe superclass does not automatically make subclasses thread-safe. But yeah, I'd not lose any sleep over this.
Michael Borgwardt
I just want to clearly document thread-friendliness of my classes.
Vilius Normantas
Odd that you claim "it just feels wrong". That's exactly what a Future does.
james
@james: it does that to report exceptions that resulted in the abortion of the task - that's what I meant with "handling a very serious error condition". And it doesn't have multiple threads accessing the exception simultaneously (the FutureTask's own thread is finished by the time the calling thread gets to see it).
Michael Borgwardt
well, i guess i don't consider an exception thrown from Future as "a very serious error condition". that description seems to me to apply to an OOME. whereas, exceptions coming from Futures may not be that uncommon depending on what type of processing you are doing. To me, Future fits the description of a "design where exceptions are routinely passed between threads".
james
Perhaps he should amend his comment to say "passed between active threads".
ILMTitan
Thank you all guys! I'm new here, but already love this place. Hope one day I'll be able to answer some questions too (at least the easy ones :)). By the way, I documented all my classes derived from Exception as not thread-safe. Just in case. Now I can sleep well :)
Vilius Normantas
+1  A: 

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.

KitsuneYMG
A: 

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.

DJClayworth
I told at least two times that this is more of a hypothetical question... It really has nothing to do with design of any program.
Vilius Normantas
+1  A: 

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.

big lep