锁定是否锁定整个对象?

时间:2018-09-05 02:28:23

标签: java multithreading concurrency operating-system

class Resource{
  public Lock lock = new ReentrantLock();

  public void A(){
    lock.lock();
    try{ .. }
    finally{
      lock.unlock();
    }
  }

  public void B(){
    lock.lock();
    try{ .. }
    finally{
      lock.unlock();
    }

  }


  public void C(){
    ... //Nothing to do with lock here
  }
}

现在可以说我有3个线程T1, T2, T3和一个名为Resource的{​​{1}}实例。

运行的第一件事是resource。现在,假设T1 calls resource.A()花费了1500分钟,如果resource.A()在第100分钟内致电T2(这意味着resource.B()的电话正在运行),会发生什么?

当我对T1进行穿孔时,它是锁定了 object 还是锁定了 method

谢谢

3 个答案:

答案 0 :(得分:1)

锁定是通过线程获得的。因此,如果一个线程X持有该锁,则其他线程要等到X释放它才能获得该锁。

在您的情况下,方法B在方法A释放锁之前无法获得该锁。

答案 1 :(得分:0)

  

运行的第一件事是T1调用resource.a()。现在,假设resource.a()花费了1500分钟,如果T2在第100分钟内致电resource.b()(这意味着T1的电话正在运行),会发生什么?

发生的事情是T2被阻塞,直到T1调用resource.b()释放锁为止。在这种情况下,它将被阻止1400分钟。

  

当我执行lock.lock()时是锁定对象还是锁定方法?

都不是。

您没有锁定Resource实例:

  1. Resource实例具有一个 intrinsic 锁...此处未使用。
  2. 调用resource.c()的其他线程不会被阻止。

您实际上并未锁定方法。锁定在方法的内部中。因此,例如,方法a或方法b可以在调用lock.lock()之前或之后释放它们。

您实际上所做的是您获得了ReentrantLock对象的锁定。 在这种情况下,方法中的三分之二会使用锁定对象,因此您实际上会锁定这些方法的相关部分由不同线程调用。

但是,如果调用是由同一线程进行的(例如,如果a()被调用为b()),则第二个调用将不会被阻止。 (这就是“可重入”在本文中的意思。)

答案 2 :(得分:0)

  

是锁定对象还是锁定方法?

都不是。它锁定了对象的 intrinsic monitor

一个常见的菜鸟错误是认为,如果线程A在某个对象o上同步,那么其他线程将无法使用或修改对象o。那根本不是真的。线程A通过输入synchronized(o)块来阻止的唯一事情是,它阻止了其他线程同时在同一对象上进行同步。

如果要确保一次只能有一个线程可以使用或修改一个对象,则必须确保将代码使用或修改的每个 位置都包装在{{1 }}在同一个对象上同步的块。


某些程序员更喜欢使用单独的私有锁对象:

synchronized

优点是,它使其他类无法使用保护您的类的私有数据的锁。