blob: a5765e27295f66e3b2f681914db7efdc6a99f4ae [file] [log] [blame]
import org.checkerframework.checker.lock.qual.*;
class BankAccount {
int balance;
void withdraw(@GuardSatisfied BankAccount this, int amount) {
this.balance = this.balance - amount;
}
void deposit(@GuardedBy("<self>") BankAccount this, int amount) {
synchronized (this) {
this.balance = this.balance + amount;
}
}
}
public class LockExample {
final @GuardedBy("<self>") BankAccount myAccount;
LockExample(@GuardedBy("<self>") BankAccount in) {
this.myAccount = in;
}
void demo1() {
myAccount.withdraw(100); // error!
synchronized (myAccount) {
myAccount.withdraw(100); // OK
}
}
@Holding("myAccount")
void demo1b() {
myAccount.withdraw(100); // OK
}
void demo1c() {
demo1b(); // error!
synchronized (myAccount) {
demo1b();
}
}
void demo2() {
myAccount.deposit(500); // OK
}
void demo3(Object someotherlock, @GuardedBy("someotherlock") BankAccount otherAccount) {
otherAccount.deposit(500); // error!
}
void demo3b(Object someotherlock, @GuardedBy("#1") BankAccount otherAccount) {
synchronized (someotherlock) {
otherAccount.deposit(500); // error!
}
}
void demo4() {
BankAccount spouseAccount = myAccount; // OK
spouseAccount.deposit(500); // OK
synchronized (myAccount) {
spouseAccount.withdraw(100); // error!
}
synchronized (spouseAccount) {
spouseAccount.withdraw(200); // OK
}
}
}