java - 在使用它之前测试弱引用 java

标签 java android weak-references

在一个多线程的 Android 项目中,我看到这样的代码:

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

...然后在其他地方:

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

我很确定检查和引用的使用之间可能存在竞争条件,如果对对象的最后一个强引用在另一个线程中的两者之间释放,但我找不到任何文档或任何比“你可能是对的”更能证实这一点的人。

我认为测试和使用弱引用的唯一正确方法是这样完成:

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

我非常有信心第二种方法是 100% 安全的,但我想知道是否有一些我不知道的 Java/编译器糖/魔法可以使第一种方法安全。

那么,第一种方法是否 100% 安全?

最佳答案

第一种方法肯定是不安全的。对 get 的每次调用都是独立的。没有什么可以阻止 GC 在第一个 get 之后和第二个之前清除弱可达对象。

javadoc状态

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.

这可以在任何时间点。调用 get(),它(可能)将一个对对象的引用暂时压入栈中,使该对象具有强可达性(它位于线程的栈上),但在与null 结束。在那一刻之后,GC 可以确定该对象是弱可达并清除其引用。然后你会得到一个 NullPointerException

使用第二种方法。但请注意,通过将其分配给变量,您可以使引用的对象具有很强的可访问性。

关于java - 在使用它之前测试弱引用 java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27628273/

相关文章:

java - 用反斜杠转义引号

java - 为 Java EE 6 中的调度程序授予安全权限

java - Camel可以用Reactor代替吗,如果可以,那么如何正确完成呢?

android - "return is not allowed here"在 kotlin lambda 中返回时

java - Intent .CATEGORY_APP_CALCULATOR : ActivityNotFoundException

java - 为什么在使用弱引用时需要找一个和监听对象生命周期完全一致的对象?

ios - ARC下的IBOutlet和viewDidUnload

java - 从 url 模式中分割字符串

Android 按键不放连续循环的方法

android - 将 Activity 实例保存在 WeakReference 中是一种好习惯吗