简体   繁体   English

Java中继承下的同步静态方法行为

[英]Synchronized static methods behaviour under inheritance in java

I read somewhere: 我在某处阅读:

If the static synchronized methods are located in different classes, then one thread can execute inside the static synchronized methods of each class. 如果静态同步方法位于不同的类中,则一个线程可以在每个类的静态同步方法中执行。 One thread per class regardless of which static synchronized method it calls. 每个类一个线程,无论它调用哪种静态同步方法。

Suppose I have below class hierarchy: 假设我有下面的类层次结构:

public class Base {
    public static synchronized void printBase() {
        System.out.println("Inside Base");
    }
}

public class Derived extends Base {
    public static synchronized void printDerived() {
        System.out.println("Inside Derived");
    }
}

1) If I have below two function calls: 1)如果我有以下两个函数调用:

Base.printBase();
Derived.printDerived();

As I understand they should not block each other and both could be executing at the same time. 据我了解,它们不应互相阻塞,并且两者可以同时执行。 As the calls are made with different classes. 由于调用是用不同的类进行的。

2) However if I have below two function calls: 2)但是,如果我有以下两个函数调用:

Derived.printBase();
Derived.printDerived();

They should be blocked by each other as they are called on the same class. 由于它们在同一类上被调用,因此应相互阻止。 Right? 对?

Or is there something more to this? 还是还有其他东西?

No, the behaviour you're describing in point 2 isn't what you'll see. 不,您在第2点中描述的行为不是您所看到的。

The synchronization object is dependant on where the method is declared, not on how it's called. 同步对象取决于方法的声明位置,而不取决于方法的调用方式。 From JLS 8.3.4.6 : JLS 8.3.4.6开始

For a class (static) method, the monitor associated with the Class object for the method's class is used. 对于类(静态)方法,使用与该方法的类的Class对象关联的监视器。

The "method's class" here is Base.class for printBase , and Derived.class for printDerived . 这里的“方法类”是Base.classprintBase ,以及Derived.classprintDerived So the code is broadly equivalent to: 因此,代码大致相当于:

public class Base {
    public static void printBase() {
        synchronized (Base.class) {
            System.out.println("Inside Base");
        }
    }
}

public class Derived extends Base {
    public static void printDerived() {
        synchronized (Derived.class) {
            System.out.println("Inside Derived");
        }
    }
}

So those two methods can be invoked from different threads regardless of how they're called, without blocking each other. 因此,无论如何调用,这两种方法都可以从不同的线程中调用,而不会互相阻塞。 (Of course, if one of the threads already owns the monitor to Derived.class , that will prevent a different thread from calling printDerived etc - I'm only talking about how these methods interact with each other.) (当然,如果其中一个线程已经拥有Derived.class的监视器,那将防止其他线程调用printDerived等-我只是在谈论这些方法如何相互影响。)

None of the two cases will cause the threads to be blocked. 两种情况都不会导致线程被阻塞。 Only the case where two threads call printBase will cause blocking. 只有两个线程调用printBase才会引起阻塞。

In the second case: 在第二种情况下:

Derived.printBase();
Derived.printDerived();

Derived.printBase(); is actually a call to Base.printBase(); 实际上是对Base.printBase();的调用Base.printBase(); .

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

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