繁体   English   中英

可重入同步

[英]reentrant synchronization

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

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();
  }

}

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

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

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

取自这里

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

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

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

你发布的内容没有重入,但是如果Amir发布,java可以重新同步。

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

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

在你的情况下,他们不是可重入的。 如果代码类似于下面那么它们将是可重入的。

  public class Foo {

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

 public synchronized void doAnotherSomething() {}
}

一旦在一个对象上获取了锁定,然后在相同的对象上就可以像上面的情况那样遍历。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM