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:
- ¿Por qué usar WeakReference en los oyentes de Android?
- ¿Hashmap débil con referencias débiles a los valores?
- ¿Cómo usar WeakReference en el desarrollo de Java y Android?
- trabajar con imágenes grandes en android
- Patrón de WeakReference / AsyncTask en android
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?
- Weakreference get () método ¿qué tan seguro es? (Android, asynctask)
- Android Asyntask: Usar referencia débil para el contexto para evitar la rotación del dispositivo de pantalla
- Android MVP WeakRefrence
- ¿Cuáles son los beneficios de usar WeakReferences?
- Controlador Android que cambia WeakReference
- Referencia débil para la llamada de red mala idea?
- Si los adaptadores en Android son clases internas estáticas o clases internas no estáticas
- SQLiteOpenHelper sincronización
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.