Esto es Lazy Loading!
Lazy Loading es una técnica que implica no cargar un componente hasta que es usado. Esta técnica evita inicializar todo el grafo de dependencias de un objeto distribuyendo la creacion de las dependencias a medida que se necesitan. Si bien puede implementarse de muchas formas (la más usada es con un Virtual Proxy) un simple proof-of-concept es el siguiente:
class Ventana {
private Widget componente;
public Widget getComponente() {
if(this.componente==null) {
this.componente = new Widget();
}
return this.componente;
}
}
El componente es creado la primera vez que se usa en lugar de inicializarse dentro del constructor de la clase. Si miramos detenidamente el código vemos que no es Thread-safe ya que más de un hilo podria volver a inicializar el componente provocando efectos impredecibles. Por ejemplo con la siguiente secuencia:
Thread 1: llamado a getComponente()
Thread 1: if( this.componente == null ) <- Componente es null entonces entra en el bloque del if
Thread 2: llamado a getComponente()
Thread 2: if( this.componente == null) <- Componente es null entonces entra en el bloque del if
Thread 2: this.componente = new Widget();
Thread 2: this.componente.value = “Soy un componente perezoso”;
Thread 1: this.componente = new Widget();
OMFG!
Tampoco es negocio sincronizar el metodo getComponente() porque lo que ganamos implementando Lazy Loading lo perdemos en las sucesivas llamadas por el costo que tiene invocar un metodo sincronizado. Una solución es usar un mecanismo llamado Double Check modificando el código anterior de esta manera.
class Ventana {
private Widget componente;
public Widget getComponente() {
if(this.componente==null) {
synchronized(this) {
if(this.component==null) {
this.componente = new Widget();
}
}
}
return this.componente;
}
}
Lo que parece una redundancia grande como una casa en realidad es un hack maravilloso, con double check la condición se evalua dos veces: una vez sin sincronizar y otra vez sincronizada. Al repetir este proceso se gana en velocidad ya que en el peor de los casos solo se ejecuta el bloque sincronizado tantas veces como threads esten utilizando el objeto en lugar de ejecutarlo tras cada llamada a getComponente. Hay que tener en cuenta que esta tecnica, si bien es un hack maravilloso, puede tener problemas con las optimizaciones que hace la JVM Hotspot, más especificamente con el reordenamiento de instrucciones que hace el compilador.
Lazy Loading en realidad abarca más conceptos, como la carga perezosa de clases, y lo que se vio recien es conocido como Lazy Instantiation. Más alla de eso me parecio bueno comentar un poco sobre el tema tras el cambio de nombre que sufrio este blog
muy bueno
Comentado por junnior01
— 12/06/2009 #