| 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(); |
| } |
| } |
| } |