在使用Java之前先测试一个弱引用 [英] Test a weak reference before using it java

查看:64
本文介绍了在使用Java之前先测试一个弱引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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();
}

我非常有信心第二种方法是100%安全的,但是我想知道是否存在一些我不知道的Java/编译器糖/魔术师,这会使第一种方法安全.

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.

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

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

推荐答案

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

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.

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 .

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.

这篇关于在使用Java之前先测试一个弱引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆