在使用java之前测试弱引用
在多线程Android项目中,我看到的代码如下:在使用java之前测试弱引用,java,android,weak-references,Java,Android,Weak References,在多线程Android项目中,我看到的代码如下: final WeakReference<MyClass> myClassObjectWeakRef = new WeakReference<MyClass>(aMyClassObject); MyClass myObject = myClassObjectWeakRef.get(); // we now have a strong reference, or null: standard
final WeakReference<MyClass> myClassObjectWeakRef =
new WeakReference<MyClass>(aMyClassObject);
MyClass myObject = myClassObjectWeakRef.get();
// we now have a strong reference, or null: standard checks apply.
if (myObject != null) {
myObject.someMethod();
}
我很确定,如果在另一个线程中,对对象的最后一个强引用是在这两个线程之间发布的,那么在检查和引用的使用之间可能存在竞争条件,但我找不到任何文档或任何人能够比“你可能是对的”更好地证实这一点
我认为测试和使用弱引用的唯一正确方法如下:
final WeakReference<MyClass> myClassObjectWeakRef =
new WeakReference<MyClass>(aMyClassObject);
MyClass myObject = myClassObjectWeakRef.get();
// we now have a strong reference, or null: standard checks apply.
if (myObject != null) {
myObject.someMethod();
}
我非常确信第二种方法是100%安全的,但我想知道是否有一些Java/编译器sugar/魔法我不知道,这会使第一种方法安全
那么,第一种方法是否100%安全?第一种方法绝对不安全。对
get
的每个调用都是独立的。没有任何东西可以阻止GC在第一个get
之后和第二个之前清除弱可达对象
美国
假设垃圾收集器在内存中的某个点确定
对象弱可达的时间。到时候会的
原子清除对该对象的所有弱引用和所有弱引用
对任何其他弱可及对象的引用
对象可以通过一系列强引用和软引用来访问
这可能发生在任何时间点。调用get()。在那一刻之后,GC可以确定对象是弱可达的,并清除其引用。然后您将得到一个NullPointerException
使用第二种方法。但请注意,通过将其分配给变量,您可以使引用对象强可访问。您可能是对的;-)不应该有任何内置的java/编译器sugar/magic来确保方法1始终有效。你对形势的理解和我对形势的理解是一致的。