Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Java class initialized by the thread which use it for the first time?

Lets assume following classes definition:

public class A {
    public final static String SOME_VALUE;

    static {
        SOME_VALUE = "some.value";
    }
}

public class B {
    private final String value = A.SOME_VALUE;
}

Assuming that the class A hasn't been loaded yet, what does happen when object of the class B is instantiated by some thread T? The class A has to be loaded and instantiated first. But my question is: if it's done in context of the thread T, or rather in context of some other (special) "classloader" thread?

like image 206
oo_olo_oo Avatar asked Mar 18 '10 13:03

oo_olo_oo


2 Answers

Take a look at sections 12.4.1 ("When Initialization Occurs") and 12.4.2 ("Detailed Initialization Procedure") of the JLS:

The procedure for initializing a class or interface is then as follows:

  1. Synchronize (§14.19) on the Class object that represents the class or interface to be initialized. This involves waiting until the current thread can obtain the lock for that object (§17.1).
  2. If initialization is in progress for the class or interface by some other thread, then wait on this Class object (which temporarily releases the lock). When the current thread awakens from the wait, repeat this step.
  3. If initialization is in progress for the class or interface by the current thread, then this must be a recursive request for initialization. Release the lock on the Class object and complete normally.
  4. If the class or interface has already been initialized, then no further action is required. Release the lock on the Class object and complete normally.
    ...

The specification states that initialization occurs in the current thread (meaning whatever thread reached a state which causes the need to initialize the class in question) but that the JVM implementation must make some pretty strict synchronization guarantees to avoid any problems.

like image 135
matt b Avatar answered Sep 17 '22 09:09

matt b


There is no special thread for loading classes. It will be from the thread which refers to the class for the first time. The ClassLoader.loadClass method is synchronized so that multiple threads trying to load the same class don't interfere.

EDIT Code to enumerate

public class Arbit {
    public static void main(String[] args) throws Exception{
        B b1 = new B("1");
        B b2 = new B("2");
        B b3 = new B("3");
        b1.start();
        b2.start();
        b3.start();
        b1.join();
        b2.join();
        b3.join();
    }
}

class B extends Thread{
    B(String s){
        setName(s);
    }
    @Override
    public void run() {

        try {
            Thread.sleep(new Random().nextInt(100));
        } catch (InterruptedException e) {
        }
        System.out.println(A.s);
    }
}

class A{
    static String s = Thread.currentThread().getName();
}
like image 23
saugata Avatar answered Sep 17 '22 09:09

saugata