Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Documenting Thread Safety (Java + Annotations)

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.

like image 328
oberger Avatar asked Dec 24 '13 17:12

oberger


People also ask

How do you prove thread-safety?

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.

How do you write a thread-safe class?

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.

What strategies we can use to achieve thread-safety?

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.


1 Answers

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.

like image 118
barfuin Avatar answered Sep 27 '22 01:09

barfuin