java - RxJava的clear(CompositeDisposable)方法内部是如何工作的?

标签 java android multithreading rx-java2

匿名类保存对封闭类的引用。

在下面的示例中,我创建了一个小型 Activity 。在 onCreate 方法中,我只是在另一个线程上添加一个计时器,添加一个 CompositeDisposable 并在 onDestroy 中清除它。

显然,如果没有CompositeDisposable,就会造成内存泄漏。使用 CompositeDisposable 它不会造成任何内存泄漏,但它是如何工作的呢?

RxJava 是否只是中断线程并在每个回调上放置 null ?你能提供一些在 RxJava 源代码中起作用的行吗?我想它就在 dispose 方法附近。

public class MainActivity extends AppCompatActivity {

private String TAG = "MainActivity";

private CompositeDisposable composite = new CompositeDisposable();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    composite.add(Flowable
            .just(1)
            .timer(90, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .subscribeWith(new DisposableSubscriber<Long>() {

                @Override
                public void onNext(Long aLong) { sayHello(); }

                @Override
                public void onError(Throwable t) { sayHello(); }

                @Override
                public void onComplete() { sayHello(); }
            }));
}

@Override
protected void onDestroy() {
    super.onDestroy();

    composite.clear();
}

public void sayHello () { Log.w(TAG, "Hello everyone"); }

最佳答案

正是在 dispose 的来源中方法。您也可以在 IDE 中跳转到库中方法的源代码,在 IntelliJ 中,它是 Windows 上的 Ctrl+B⌘B在 Mac 上,在 Eclipse 中为 F3

无论如何,这是 dispose 的来源方法(我的评论):

@Override
public void dispose() {
    if (disposed) { // nothing to do
        return;
    }
    OpenHashSet<Disposable> set; // this is the same type as our field that holds the Disposables
    synchronized (this) {
        if (disposed) { 
            return; // another thread did it while we got our lock, so nothing to do
        }
        disposed = true; // setting this flag is safe now, we're the only ones disposing
        set = resources; // the references are now in this local variable
        resources = null; // our field no longer has the references
    }

    dispose(set); // from here on out, only this method has the references to the Disposables
}

然后是dispose(OpenHashSet<Disposable>)的完整代码我们在上面最后一行调用的方法(主要是错误处理,我认为这是不言自明的):

/**
 * Dispose the contents of the OpenHashSet by suppressing non-fatal
 * Throwables till the end.
 * @param set the OpenHashSet to dispose elements of
 */
void dispose(OpenHashSet<Disposable> set) {
    if (set == null) {
        return;
    }
    List<Throwable> errors = null;
    Object[] array = set.keys();
    for (Object o : array) {
        if (o instanceof Disposable) {
            try {
                ((Disposable) o).dispose();
            } catch (Throwable ex) {
                Exceptions.throwIfFatal(ex);
                if (errors == null) {
                    errors = new ArrayList<Throwable>();
                }
                errors.add(ex);
            }
        }
    }
    if (errors != null) {
        if (errors.size() == 1) {
            throw ExceptionHelper.wrapOrThrow(errors.get(0));
        }
        throw new CompositeException(errors);
    }
}

如您所见,在该方法的末尾,set现在可以进行垃圾收集,因为没有人持有对它的引用。

关于java - RxJava的clear(CompositeDisposable)方法内部是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42873048/

相关文章:

java - 为什么 Lambda 在初始化后生成相同的加密 key 以及如何修复它?

java - 为什么 JVM 不从数据库加载类?

android - 将 JNIEnv 或上下文从 Java 传递给 Go

Android - startActivityForResult 获取用户位置?

android - 将帧动画应用于 Toast View

multithreading - 如何停止执行使用 HTTPClient 创建的请求

java - 如何在 NetBeans 中正确导入 Apache HttpClient?

java - 任务“:app:transformClassesWithMultidexlistForDebug”执行失败

具有多个对象/锁的 Java 同步

方法中的 C# 线程