锁定锁定整个对象?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锁定锁定整个对象?相关的知识,希望对你有一定的参考价值。

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和一个名为Resourceresource实例。

第一件事是T1 calls resource.A()。现在,让我们说resource.A()需要1500分钟,如果T2在第100分钟呼叫resource.B()(意味着来自T1的呼叫正在运行),会发生什么?

当我穿上lock.lock()时它是锁定物体还是锁定了方法?

谢谢

答案

锁是通过线程获得的。因此,如果一个线程X持有锁,则其他线程在X释放之前无法获取锁。

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

另一答案

运行的第一件事是T1调用resource.a()。现在,让我们说resource.a()需要1500分钟,如果T2在第100分钟呼叫resource.b()(意味着来自T1的呼叫正在运行),会发生什么?

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

当我执行lock.lock()它是否锁定对象或锁定方法?

也不是真的。

你没有锁定Resource实例:

  1. Resource实例有一个固有的锁...这里没有使用。
  2. 调用resource.c()的其他线程不会被阻止。

你实际上没有锁定方法。锁定在方法内部。因此,例如,方法a或方法b可以在调用lock.lock()之前或释放之后执行操作。

你实际上做的是你获得了ReentrantLock对象的锁定。在这种情况下,三个方法中有两个使用该锁定对象,因此您实际上是锁定这些方法的相关部分以防止不同线程的调用。

但是,如果调用是由同一个线程进行的(例如,如果a()称为b()),那么第二个调用将不会被阻止。 (这就是“可重入”在这种情况下的意思。)

另一答案

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

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

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

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


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

private static final Object lock = new Object();

public void mymethod(...) {
    synchronized(lock) {
        ...access to this is protected by lock...
    }
}

它的优点是,它否认其他类能够使用锁保护您的类的私有数据。

以上是关于锁定锁定整个对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不锁定活动方向的情况下锁定片段方向?

Android 片段不保存状态,在旋转/屏幕锁定/返回时崩溃

按下锁定/主页按钮时的通知,单击返回选项卡片段时的通知

我在哪里更改此 Python 代码片段以将临时文件保存在 tmp 文件夹中?

锁定AppendAllText与TextWriter

java中,用synchronized会锁定当前对象,这个对象指的是它包涵的代码块,还是一个类实例