2010-03-18 14 views
5

supongamos siguientes clases definición:¿La clase de Java se inicializa por el hilo que lo usa por primera vez?

public class A { 
    public final static String SOME_VALUE; 

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

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

Suponiendo que la clase A no se ha cargado todavía, lo que sucede cuando el objeto de la clase B se crea una instancia de un poco de hilo T? La clase A tiene que cargarse e instanciarse primero. Pero mi pregunta es: ¿si se hace en el contexto del hilo T, o más bien en el contexto de algún otro hilo (especial) "cargador de clases"?

Respuesta

4

No hay un hilo especial para cargar clases. Será del hilo que se refiere a la clase por primera vez. El método ClassLoader.loadClass está sincronizado, por lo que varios subprocesos que intenten cargar la misma clase no interfieren.

EDITAR Código enumerar

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

Creo que desde JDK7 puede tener dos clases del mismo cargador de clases inicializando al mismo tiempo. –

+0

@Tom Pero eso no causaría problemas, p. si en un método igual pongo this.getClass() == obj.getClass() – saugata

+0

Cada clase individual se inicializará una vez, pero puede haber múltiples clases diferentes en el mismo cargador de clases que se inicializan al mismo tiempo. Esto no puede suceder actualmente debido a la cerradura notada en su respuesta. (Creo que esto es correcto.) –

5

Tome un vistazo a las secciones 12.4.1 ("Cuando ocurra la inicialización") y 12.4.2 ("procedimiento de inicialización detallada") de la JLS:

Los El procedimiento para inicializar una clase o interfaz es el siguiente:

  1. Sincronice (§14.19) en el objeto de Clase que representa la clase o interfaz a ser inicializada. Esto implica esperar hasta que el hilo actual pueda obtener el bloqueo para ese objeto (§17.1).
  2. Si la inicialización está en curso para la clase o la interfaz por algún otro hilo, espere en este objeto de clase (que libera temporalmente el bloqueo). Cuando el hilo actual despierta de la espera, repita este paso.
  3. Si la inicialización está en curso para la clase o la interfaz por el hilo actual, entonces esta debe ser una solicitud recursiva para la inicialización. Libere el bloqueo en el objeto Class y complete normalmente.
  4. Si la clase o la interfaz ya se ha inicializado, no se requieren más acciones. Libere el bloqueo en el objeto Class y complete normalmente.
    ...

La especificación establece que la inicialización se produce en el hilo actual (es decir, cualquiera que sea el hilo alcanza un estado que hace que la necesidad de inicializar la clase en cuestión), pero que la aplicación JVM debe hacer algo bastante estrictas garantías de sincronización para evitar cualquier problema.

+0

+1 para hacer referencia al JLS – medopal

Cuestiones relacionadas