At the moment I am doing some more work on evaluating tracematches ahead-of-time. One tracematch patten that we use in our benchmarks we called ASyncIter, a simplified version of which looks as follows:
tracematch(Collection c) { sym sync after returning: call(* Collections.synchr*(..)) && args(c); sym iter before: call(* Collection.iterator()) && target(c); sync iter { if(!Thread.holdsLock(c)) error(``Have to synchronize iterator at ''+thisJoinPoint); } }
This tracematch reports an error if you create a synchronized collection and then iterate over this collection without holding a lock on the collection object. According to the JDK javadoc this is forbidden as it can lead to a race condition. One has to use synchronized collections as follows: