同步对象锁定混淆

时间:2013-08-07 14:49:50

标签: java multithreading

我正在学习K& B线程章节。我正在读关于同步的内容。这是一个例子 K&安培; B

public class AccountDanger implements Runnable {
  private Account account = new Account();
  public void run() {
    for(int x =0 ; x < 5 ; x++){
      makeWithdrawl(10);
      if(account.getBalance() < 0 ){
        System.out.println("account is overdrawn");
      }
    }
  }
  public static void main(String[] args){
    AccountDanger accountDanger = new AccountDanger();
    Thread one = new Thread(accountDanger);
    Thread two = new Thread(accountDanger);
    one.setName("Fred");
    two.setName("Lucy");
    one.start();
    two.start();
  }

  private synchronized void makeWithdrawl(int amt){
    if(account.getBalance() >= amt){
      System.out.println(Thread.currentThread().getName() + " is going to withdraw");

    try{
      Thread.sleep(500);
    }
    catch(InterruptedException e) {
      e.printStackTrace();
    }
    account.withdraw(amt);
    System.out.println(Thread.currentThread().getName() + " completes the withdrawl");
   }
    else{
      System.out.println("Not enough in account for " + Thread.currentThread().getName() + " to withdraw " +
        account.getBalance());
    }
 }
}

K&amp; B谈论同步方法和同步块。以下是K&amp; B的段落。

  

当一个方法从synchronized块内执行代码时,代码   据说是在同步的上下文中执行。当你   同步一个方法,用于调用方法的对象是   必须获取其锁的对象。但是当我们同步块时   代码,您必须指定要用作锁的对象锁。

因此,在此示例中,是否会在AccountDanger实例或Account对象上获取锁定? 我认为应该是AccountDanger。我觉得正确吗?如果是AccountDanger对象, 并且一个线程获得了AccountDanger的锁定,任何其他线程是否能够调用非同步方法?

2 个答案:

答案 0 :(得分:0)

  

因此,在此示例中,将在AccountDanger上获取锁定   实例或帐户对象?

是。我见过的一个技巧是在this上只有一小段实际需要同步的代码时进行同步。例如:

int balance = -1;
synchronized(this) {
  balance = account.getBalance();
  account.withdraw(amt);
}
//IO, etc. after that.

总的来说,这会加快速度。

答案 1 :(得分:0)

private synchronized void makeWithdrawl(int amt){
     //is implicitly acquiring lock on this object (AccountDanger object)              
}

因此在示例中,调用此方法的第一个线程将进入synchronized块获取this对象监视器并保留它,除了第一个线程本身之外没有其他线程可以再次获取监视器锁定this。调用此方法的所有其他线程将阻塞,直到第一个线程释放锁并释放监视器。

注意:用于同步块的锁本质上是Re-entrant