package ar.com.javacuriosities.references;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import ar.com.javacuriosities.references.util.Foo;
/*
* Las ReferenceQueue nos brinda un mecanismo de notificación
* para poder saber cuando una referencia esta a punto de ser recolectada.
* Las ReferenceQueue pueden ser suministradas como parámetros a cualquiera
* de los tipos de referencias.
*/
public class Step5ReferenceQueues {
private static Foo foo;
public static void main(String[] args) {
// Creamos una referencia a un objeto Foo del tipo Strong Reference
foo = new Foo();
/*
* Creamos una ReferenceQueue en la cual registramos la referencia la cual será agregada
* a la lista luego que la referencia alcance su estado de "reachability"
*
* Niveles de reachibility
* - Strong
* - Soft
* - Weak
* - Finalizer
* - Phantom
* - Unreachable
*/
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
/*
* Creamos una WeakReference y la asignamos a la cola que creamos anteriormente
* - Si usamos una WeakReference sabemos cuando este objeto no es referenciado, pero antes de ejecutar finalize
* - Si usamos una PhantomReference el objeto esta por ser limpiado de la memoria luego de finalize
*/
WeakReference<Object> weakReference = new WeakReference<Object>(foo, queue);
// Iniciamos un Thread que se va a encargar de limpiar la referencia al objeto
new Thread(new Task()).start();
try {
// Aquí sacamos la referencia de la cola, esto es bloqueante hasta que encuentra alguna
Reference<?> reference = queue.remove();
if (reference == weakReference) {
System.out.println("The object is not more referenced");
}
} catch (InterruptedException e) {
// Log and Handle exception
e.printStackTrace();
}
}
private static final class Task implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("Asigning object to NULL");
// Hacemos al objeto elegible por el GC
foo = null;
System.out.println("Executing GC...");
// Sugerimos al GC correr
System.gc();
} catch (Exception e) {
// Log and Handle exception
e.printStackTrace();
}
}
}
}