import org.checkerframework.checker.lock.qual.*; public class Fields { class MyClass { public Object field; } static @GuardedBy("Fields.class") MyClass lockedStatically; static synchronized void ssMethod() { lockedStatically.field = new Object(); } @GuardedBy("lockingObject") MyClass locked; final Object lockingObject = new Object(); synchronized void wrongLock1() { // locking over wrong lock //:: error: (lock.not.held) locked.field = new Object(); // error } synchronized void wrongLock2() { // locking over wrong lock synchronized (this) { //:: error: (lock.not.held) locked.field = new Object(); // error } } void rightLock() { synchronized (lockingObject) { locked.field = new Object(); } // accessing after the synchronized object //:: error: (lock.not.held) locked.field = new Object(); // error } @Holding("lockingObject") void usingHolding() { locked.field = new Object(); } @GuardedBy("this") MyClass lockedByThis; void wrongLocksb() { // without locking //:: error: (lock.not.held) lockedByThis.field = new Object(); // error synchronized (Fields.class) { //:: error: (lock.not.held) lockedByThis.field = new Object(); // error } } void rightLockb() { synchronized (this) { lockedByThis.field = new Object(); } // accessing after the synchronized object //:: error: (lock.not.held) lockedByThis.field = new Object(); // error } synchronized void synchronizedMethodb() { lockedByThis.field = new Object(); } void test() { // synchronized over the right object final Fields a = new Fields(); final Fields b = new Fields(); synchronized (this) { lockedByThis.field = new Object(); //:: error: (lock.not.held) a.lockedByThis.field = new Object(); // error //:: error: (lock.not.held) b.lockedByThis.field = new Object(); // error } synchronized (a) { //:: error: (lock.not.held) lockedByThis.field = new Object(); // error a.lockedByThis.field = new Object(); //:: error: (lock.not.held) b.lockedByThis.field = new Object(); // error } synchronized (b) { //:: error: (lock.not.held) lockedByThis.field = new Object(); // error //:: error: (lock.not.held) a.lockedByThis.field = new Object(); // error b.lockedByThis.field = new Object(); } } }