猿问

混淆Java同步方法、synchronized(this)和synchronized类

由于 Java 的同步概念,我很困惑。


让我们假设以下类:


class MyClass {

  public synchronized void foo() { //do something }

  public void bar() {

    synchronized(this) { //do something }

  }

  public void normal() { //do something }

}

据我所知,foo和bar方法的工作原理相同。


但是,在线程A进入bar方法并通过 同步实例后synchronized(this),任何线程都可以调用正常方法吗?


据我所知,有些线程不管调用方法都可以调用普通foo方法。但我不确定何时bar调用该方法,因为它同步了一个实例。


另外,让我们假设以下方法:


class StaticMyClass {

  public static synchronized void fooStatic() { //do something }

  publi static void barStatic() {

    synchronized(StaticMyClass.class) { //do something }

  }

  public static void normalStatic() { //do something }

}

在这里,有同样的问题。线程 A 进入临界区后,即synchronized(StaticMyClass.class)或fooStatic方法,任何线程都可以调用normalStatic?

我认为,fooStatic和normalStatic可以独立调用,但barStatic并normalStatic不能。如果错了,为什么?


我感谢您的帮助。


MMMHUHU
浏览 209回答 3
3回答

慕丝7291255

据我所知,foo和bar方法的工作一样。正确。它们都在 上同步this。线程 A 进入bar方法并通过 同步实例后synchronized(this),任何线程都可以调用normal方法吗?是的。正确的。据我所知,normal无论调用foo方法,某些线程都可以调用方法。但我不确定何时调用 bar 方法。因为它同步了一个实例。foo并且bar是一样的。它们都在 上同步this。该normal方法不同步任何东西。因此,它可以随时从任何地方调用,并且不会在方法调用时或内部阻塞。在您的术语中,该normal方法不是关键部分1。静态的第二个例子在这里,有同样的问题。线程 A 进入临界区后,任何线程都可以调用synchronized(StaticMyClass.class)或fooStatic方法normalStatic吗?是的。在fooStatic和barStatic上都能够同步StaticMyClass.class。我认为,呼叫fooStatic和normalStatic可以独立调用,但barStatic并normalStatic不能。不正确。在normalStatic不被挡fooStaticOR barStatic。我不确定你从哪里得到normalStatic可能被阻塞的想法......但它是一个正常的方法调用并且不获取任何内在锁,所以它不能被锁阻塞。你的第三个例子不清楚。代码显示了一件事,但问题提出了不同/不相关的问题。1 - 如果(例如)foo或在持有内在锁时bar调用它可能会有点混乱normal。然后normal代码将有效地位于临界区,因为调用者持有锁。但它 ( normal) 通常不会知道这一点。这就是为什么我更喜欢避免使用“临界区”术语的原因。

不负相思意

如果您没有指定谁是监视器,那么对于实例方法,监视器就是实例(this),对于静态方法,监视器就是类(YourClass.class)。这段代码public synchronized void foo() { //do something }和这个一样public void foo() {   synchronized(this) { //do something }}和这段代码public static synchronized void fooStatic() { //do something }和这个一样public static void fooStatic() {    synchronized(StaticMyClass.class) { //do something }    }所以,在这两种情况下,foo 和 bar 都是依赖的(同时只有一个线程),而 normal 可以独立调用。

largeQ

但是线程A进入bar方法并通过synchronized(this)同步实例后,任何线程都可以调用正常的方法吗?对同一对象的同步方法的两次调用不可能交错。当一个线程正在为一个对象执行同步方法时,所有其他调用同一个对象的同步方法的线程都会阻塞(挂起执行),直到第一个线程完成对对象的处理。如果您尝试调用其他未同步的方法,则有可能。线程A进入synchronized(StaticMyClass.class)或fooStatic方法的临界区后,任何线程都可以调用normalStatic吗?我认为,调用 fooStatic 和 normalStatic 可以独立调用,但是 barStatic 和 normalStatic 不能。如果错了,为什么?其他未同步的方法可以独立调用,但是当您调用 barStatic() 时,不可能调用其他方法,因为您正在同步整个类。其他线程,必须等到当前线程完成执行。
随时随地看视频慕课网APP

相关分类

Java
我要回答