I am attempting to update an application that uses dependency injection, in doing so, I am trying to document each class (that needs it) with a "thread-safety" annotation, both for other coders and for bug checkers.
If I have a service class, as follows:
@ImplementedBy(FooImpl.class)
public interface FooSrvc {
}
and it's associated implementation
class FooImpl implements FooSrvc {
}
*Should I document or annotate both the Interface and the concrete Implementation with thread-safe annotations? Just the service, because it's public, just the implementation?*e.g. for both:
@javax.annotation.concurrent.ThreadSafe
@org.checkthread.annotations.ThreadSafe
@ImplementedBy(FooImpl.class)
public interface FooSrvc {
}
@javax.annotation.concurrent.ThreadSafe
@org.checkthread.annotations.ThreadSafe
class FooImpl implements FooSrvc {
}
Note - I am using two different thread-safety annotation sets to use an older concurrency bug finder CheckThread (where I couldn't find documentation that supports the jsr-305 annotations) and FindBugs.
Thank you.
To test if the combination of two methods, a and b, is thread-safe, call them from two different threads. Put the complete test in a while loop iterating over all thread interleavings with the help from the class AllInterleavings from vmlens. Test if the result is either an after b or b after a.
To make these classes thread-safe, you must prevent concurrent access to the internal state of an instance by more than one thread. Because Java was designed with threads in mind, the language provides the synchronized modifier, which does just that.
It's also possible to achieve thread-safety using the set of atomic classes that Java provides, including AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference. Atomic classes allow us to perform atomic operations, which are thread-safe, without using synchronization.
That depends:
If you annotate only the interface, then the meaning is "Every implementation of this interface is guaranteed to be thread-safe." This is a tough call, because it will be difficult to ensure that implementors don't violate the contract.
If you annotate only the implementation, then you're explicitly allowing other implementations of the interface not to be thread-safe. This is much more comfortable from a governance standpoint, but not as useful to callers of the interface.
Annotating both is redundant, because the annotation on the interface cannot be overridden by annotations on the implementation (would violate polymorphism). Still, this may be the preferred option because it has the better tool support.
The individual static analysis tools you are using may well require you to go with option 3. I don't know CheckThread well enough to comment. The FindBugs thread-safety detectors, however, are so rudimentary that it doesn't really matter; if FindBugs is your main tool for this, then I would recommend option 3 plus some Javadoc on the interface telling developers that the thread-safety annotation is not enforced, so they must also check the implementation to be sure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With