Search code examples
javamultithreadingclassloader

is class locking related to java classloader?


Looks like I am missing important concept on locking a class and it's related classloading event.As per my knowledge in java we can use any class only if classloader has already loaded the class ( byte code ) in memory. Based on this assumption I was thinking that "static block of SharedQ class should execute when statement synchronized (SharedQ.class) { ... } executes in below code". But thats not the same. Can anyone please explain what is happening here exactly.

public class VerifyClassLoadingOnClassLock {
    public static void main(String[] args) {
        show();
    }

    private static void show() {
        synchronized (SharedQ.class) {
            System.out.println(" Method Show() executing from Main() .... ");
        }       
    }
} 



public class SharedQ {  
    static {
        System.out.println(" Classloader is loading SharedQ ");
    }

    public static void writeStream() {
        // some multiThread code here
    }
}

Output is : Method Show() executing from Main() ....


Solution

  • The class will have been loaded, but not necessarily initialized. Basically, there's a Class object available when you synchronize on it, but until something uses a member of the class, it doesn't have to be initialized.

    From the JVM specification section 5.5:

    Initialization of a class or interface consists of executing its class or interface initialization method (§2.9).

    A class or interface may be initialized only as a result of:

    • The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references the class or interface (§new, §getstatic, §putstatic, §invokestatic). All of these instructions reference a class directly or indirectly through either a field reference or a method reference.
    • Upon execution of a new instruction, the referenced class or interface is initialized if it has not been initialized already.
    • Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.
    • The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic).
    • Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.
    • The initialization of one of its subclasses.
    • Its designation as the initial class at Java Virtual Machine start-up (§5.2).

    Prior to initialization, a class or interface must be linked, that is, verified, prepared, and optionally resolved.

    Section 5 of the specification talks a lot about all of this - in particular, it differentiates between loading, linking and verification.