Pruebe una referencia débil antes de usar java

En un proyecto con varios hilos de Android, veo un código como este:

final WeakReference<MyClass> myClassObjectWeakRef = new WeakReference<MyClass>(aMyClassObject); 

… entonces en otro lugar:

 if (myClassObjectWeakRef.get() != null) { myClassObjectWeakRef.get().someMethod(); } 

Estoy bastante seguro de que hay una posible condición de carrera entre el cheque y el uso de la referencia, si la última referencia fuerte al objeto se libera entre los dos en otro hilo, pero no puedo encontrar ninguna documentación o cualquier persona que / Quien puede confirmar esto mejor que con un "probablemente tienes razón".

Yo creo que la única manera correcta de probar y usar una referencia débil se hace así:

 MyClass myObject = myClassObjectWeakRef.get(); // we now have a strong reference, or null: standard checks apply. if (myObject != null) { myObject.someMethod(); } 

Estoy muy seguro de que el segundo método es 100% seguro, pero me pregunto si hay algo de Java / compilador de azúcar / magia que no conozco, lo que haría el primer método seguro.

Por lo tanto, es el primer método 100% seguro, o no?

El primer método es definitivamente inseguro. Cada llamada a get es independiente. No hay nada que impida que el GC despeje el objeto débilmente accesible después del primer get y antes del segundo.

Los estados javadoc

Supongamos que el recolector de basura determina en un cierto punto en el tiempo que un objeto es débilmente accesible. En ese momento, borrará atómicamente todas las referencias débiles a ese objeto y todas las referencias débiles a cualquier otro objeto débilmente accesible desde el cual ese objeto sea alcanzable a través de una cadena de referencias fuertes y suaves.

Eso puede estar en cualquier momento. Llamar get() , que (potencialmente) empuja una referencia al objeto en la pila temporalmente hace que el objeto sea fuertemente accesible (está en la pila de un hilo), pero esa capacidad de alcance desaparece en el momento en que termina la comparación con null . Después de ese momento, el GC puede determinar que el objeto es débilmente accesible y borrar su referencia. Entonces obtendría una NullPointerException .

Utilice su segundo método. Pero tenga en cuenta que al asignarla a una variable, está haciendo que el objeto referenciado sea fuertemente accesible.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.