Test a weak reference before using it java

≯℡__Kan透↙ 提交于 2019-12-09 02:12:17

问题


In a multithreaded Android project, I'm seeing code like this:

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

...then somewhere else:

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

I'm pretty sure there is a possible race condition between the check and the use of the reference, if the last strong reference to the object is released between the two in another thread, but I can't find any documentation or anyone which/who can confirm this better than with a "you're probably right".

I would think the only right way to test & use a weak reference is done like this:

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

I'm very confident that the second method is 100% safe, but I wonder if there is some Java/compiler sugar/magic that I don't know about, which would make the first method safe.

So, is the first method 100% safe, or not?


回答1:


The first method is definitely unsafe. Each call to get is independent. There is nothing preventing the GC from clearing the weakly reachable object after the first get and before the second.

The javadoc states

Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references.

That can be at any point in time. Calling get(), which (potentially) pushes a reference to the object on the stack temporarily makes the object strongly reachable (it's on a thread's stack), but that reach-ability disappears the moment the comparison with null finishes. After that moment, the GC can determine that the object is weakly reachable and clear its reference. You'd then get a NullPointerException.

Use your second method. But note that by assigning it to a variable, you are making the referenced object strongly reachable.



来源:https://stackoverflow.com/questions/27628273/test-a-weak-reference-before-using-it-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!