2014-12-23 12 views
16

W wielowątkowym projektem Android, widzę kod tak:test słaby odniesienia przed użyciem Java

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

... potem gdzieś indziej:

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

jestem ładna że istnieje pewna możliwość wyścigu między sprawdzeniem a użyciem referencji, jeśli ostatnie silne odwołanie do obiektu zostanie zwolnione między dwoma w innym wątku, ale nie mogę znaleźć żadnej dokumentacji ani nikogo, kto/może potwierdzić to lepiej niż z "prawdopodobnie masz rację".

Myślę jedyną właściwą drogę do przetestowania & użyciu słabego odniesienia odbywa się to tak:

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

Jestem przekonana, że ​​druga metoda jest w 100% bezpieczne, ale zastanawiam się, czy istnieje trochę java/kompilatora cukru/magii, o których nie wiem, co uczyniłoby pierwszą metodę bezpieczną.

Tak, to pierwsza metoda w 100% bezpieczne, czy nie?

+1

pewnie masz rację ;-) – petey

+3

Tam nie powinno być żadnych wbudowanych w Java/cukier kompilator/magic celu zapewnienia metoda nr 1 zawsze będzie działać. Twoje zrozumienie sytuacji pasuje również do mojego zrozumienia sytuacji. – NoseKnowsAll

+0

Dzięki za pytanie –

Odpowiedz

10

Pierwsza metoda jest zdecydowanie niebezpieczna. Każde połączenie z numerem get jest niezależne. Nic nie stoi na przeszkodzie, aby GC usunął słabo osiągalny obiekt po pierwszym, i przed drugim, G2.

W javadoc stany

Załóżmy, że kolektor śmieci określa w pewnym momencie w czasie że obiekt jest słabo osiągalny. W tym czasie będzie to niepodzielnie usuwać słabi odniesienia do tego obiektu i słabi odniesienia do innych słabo nieosiągalnego przedmiotów z którym obiekt jest osiągalny za pośrednictwem łańcucha silnych i miękkich odniesienia.

To może być w dowolnym momencie. Wywołanie get(), które (potencjalnie) popycha odniesienie do obiektu na stosie tymczasowo czyni obiekt silnie nieosiągalnego (to na stosie wątku jest), ale to osiągnąć, umiejętność zniknie chwili porównanie z null wykończeń. Po tym czasie GC może ustalić, czy obiekt jest słabo osiągalny i czynić jego odniesienie. Otrzymasz wtedy NullPointerException.

Użyj drugą metodę. Zauważ jednak, że przypisując ją do zmiennej, czynisz obiekt referencyjny silnie osiągalnym.

Powiązane problemy