import checkers.lock.quals.*; public class Fields { @GuardedBy("lockingObject") Object locked; Object lockingObject; synchronized void wrongLocks() { // without locking //:: (unguarded.access) locked.toString(); // error // locking over wrong lock synchronized(this) { //:: (unguarded.access) locked.toString(); // error } } void rightLock() { synchronized(lockingObject) { locked.toString(); } // accessing after the synchronized object //:: (unguarded.access) locked.toString(); // error } @Holding("lockingObject") void usingHolding() { locked.toString(); } @GuardedBy("this") Object lockedByThis; void wrongLocksb() { // without locking //:: (unguarded.access) lockedByThis.toString(); // error synchronized(Fields.class) { //:: (unguarded.access) lockedByThis.toString(); // error } } void rightLockb() { synchronized(this) { lockedByThis.toString(); } // accessing after the synchronized object //:: (unguarded.access) lockedByThis.toString(); // error } synchronized void synchronizedMethodb() { lockedByThis.toString(); } void test() { // synchronized over the right object Fields a = new Fields(); Fields b = new Fields(); synchronized(this) { lockedByThis.toString(); //:: (unguarded.access) a.lockedByThis.toString(); // error //:: (unguarded.access) b.lockedByThis.toString(); // error } synchronized(a) { //:: (unguarded.access) lockedByThis.toString(); // error a.lockedByThis.toString(); //:: (unguarded.access) b.lockedByThis.toString(); // error } synchronized(b) { //:: (unguarded.access) lockedByThis.toString(); // error //:: (unguarded.access) a.lockedByThis.toString(); // error b.lockedByThis.toString(); } } }