A few days ago I blogged about a few really subtle data races that can easily be triggered in the JDK, when invoking methods like containsAll on synchronized (!) collections. In the following code you can get a race on sl2 because sl1.containsAll(sl2) synchronizes on sl1 only, not on the argument sl2!
List sl1 = Collections.synchronizedList(new ArrayList()); List sl2 = Collections.synchronizedList(new ArrayList()); sl1.containsAll(sl2);
Here are now two easy aspect-oriented solutions to this problem, first in form of a tracematch, then in form of a normal AspectJ aspect. You can download the tracematch here and the plain AspectJ aspect here.