可重入同步

Min*_*ang 6 java

你能告诉我以下的调用是否可以重入?

public class Foo {

  public synchronized void doSomething() {}

  public synchronized void doAnotherSomething() {}
}

public class Too {

  private Foo foo;

  public synchronized void doToo() {
    foo.doSomething();
    //...other thread interfere here....
    foo.doAnotherSomething();
  }

}
Run Code Online (Sandbox Code Playgroud)

方法doToo()可重入的2个连续调用?我不确定这种情况,因为foo.doSomething()方法获取并释放内部锁,两次调用之间没有嵌套同步.是否存在其他线程可能在两次调用之间发生干扰的情况?

Ami*_*hum 25

首先,关于Java中的重入锁:

Java中的同步块是可重入的.这意味着,如果Java线程进入同步的代码块,从而对监视器对象的锁定进行同步,则该线程可以输入在同一监视器对象上同步的其他Java代码块.

采取从这里.

您描述的两个连续呼叫(in doToo)将不会受到干扰,除非另一个对象具有对Too私有的引用Foo,因为要访问foo,需要锁定Too.但是,调用不会调用重新进入,因为每次调用都会获取并释放锁.如果doSomething被叫,它们将是可重入的,doAnotherSomething反之亦然.


ami*_*ngh 5

首先,锁适用于对象,因此需要创建对象,然后应用锁。

are 2 continuous invocations in method doToo() reentrant? I

在你的情况下,它们是不可重入的。如果代码如下所示,那么它们将是可重入的。

  public class Foo {

 public synchronized void doSomething() {
        doAnotherSomething();
}

 public synchronized void doAnotherSomething() {}
}
Run Code Online (Sandbox Code Playgroud)

一旦在一个对象上获得了锁,那么它就可以像上面的情况一样在同一个对象上进行遍历。


Pyr*_*rce 5

这完全取决于其他线程正在访问什么。另一个线程可以在这些函数之间接管 CPU 吗?是的。会出现竞争条件吗?取决于很多因素。

从您发布的内容来看, foo.doSomething 将被锁定在 foo 上,然后释放,然后在进入 doAnotherSomething 时再次锁定。因此,如果另一个未锁定在同一 Too 对象上的线程尝试操作 foo,它们将能够在 doSomething 和 doAnotherSomething 之间执行此操作。如果每个人在操作底层 foo 对象之前都在同一个 Too 对象上同步,那么 foo 的这两个方法在调用之间将不会进行状态操作,因为 Too 对象方法将阻塞其他线程直到完成。因此,是否有问题取决于您的其他访问器。

从您发布的内容来看,这里没有可重入,但正如阿米尔发布的那样,java可以使用可重入同步。