首页 > 解决方案 > 等待对象创建或如果它已经存在则立即访问它

问题描述

我今天遇到了以下问题:我们有一个类Foo,里面有一个实例Bar。在类的生命周期中的某个时间点调用一个方法initBar()(这是非常异步的,很多 RxJava)并且它确实bar = new Bar()

现在,问题是我想访问bar其他方法的内部,doStuff()不能保证在之后调用它initBar(),所以它bar可以仍然存在null或已经存在。

如果bar已经存在,我想立即analyze(bar)同步运行一个函数,如果它仍然存在null- 我想安排它运行一次bar(作为initBar()调用的一部分)。

额外问题:如何指定analyze(bar)应该在哪个线程上执行;如果要访问多个方法怎么办bar;如何安全地取消这些。

现在,我知道如何使用 RxJava 实现这一点:添加额外的PublishSubject<Bar> subject并订阅它,同时调用.repeat()以获取已设置的值,然后从initBar()do subject.onNext(bar)。这很容易。它甚至涵盖了从多个地方访问它并指定一个线程来运行代码的情况。

但我觉得我在这里重新发明了一个轮子——当你想访问一个对象而不担心它是否已经设置时,可能有解决这类问题的方法。是否应该将其视为Promise并使用JDeferredCompletableFuture完成?或者已经有一些很好的食谱了吗?必须有一些干净和简单的东西......RxJava

Foo这是供参考的完整代码:

class Foo {
    Bar bar;

    void initBar() { bar = new Bar(); }

    void doStuff() {
         //This is the missing piece
         doWhenBar(bar -> analyze(bar));
    }

    void lifecycle1() {
        Observable.create(..)
            ...
            .doOnNext(this::initBar())
            ...
    }

    void lifecycle2() {
        Observable.create(..)
            ...
            .subscribe(this::doStuff())
    }

    //More methods where lifecycle1() and lifecycle2() can be called in random order
    ...
}

标签: javamultithreadingconcurrencyrx-java

解决方案


如果bar只创建一次,请使用 a SingleSubject,现在您可以对Bar被创建做出反应:

class Foo {
    final SingleSubject<Bar> bar = SingleSubject.create();

    void initBar() { bar.onSuccess(new Bar()); }

    Single<Bar> doStuff() {
         //This is the missing piece
         return bar.observeOn(Schedulers.computation())
         .doOnSuccess(b -> analyze(b));
    }

    void lifecycle1() {
        Observable.create(..)
        ...
        .doOnNext(this::initBar())
        ...
    }

    void lifecycle2() {
        Observable.create(..)
        ...
        .concatMapSingle(this::doStuff)
        .subscribe(...)
    }

// More methods where lifecycle1() and lifecycle2()
// can be called in random order
...
}

推荐阅读