import java.util.*; public aspect TMASyncContainsAll { Object tracematch(Collection t, Collection a) { sym sync1 after returning(t): !within(ASyncContainsAll) && call(* Collections.synch*(..)); sym sync2 after returning(a): !within(ASyncContainsAll) && call(* Collections.synch*(..)); sym starAll around(t,a): !within(ASyncContainsAll) && call(* Collection.*All(Collection)) && target(t) && args(a); sync1 sync2 starAll { //if we don't have the lock on a if(t!=a && !Thread.holdsLock(a)) { //give error System.err.println("Must synchronize argument collection at: " + thisJoinPointStaticPart.getSourceLocation()); //actually *do* synchronize and proceed synchronized(a) { return proceed(t,a); } } return proceed(t,a); } } } class ASyncContainsAllTest { public static void main(String[] args) { List l1 = Collections.synchronizedList(new ArrayList()); List l2 = Collections.synchronizedList(new ArrayList()); l1.addAll(l2); } }