等待对象创建,或者如果已经存在则立即访问它

时间:2018-10-27 05:15:01

标签: java multithreading concurrency rx-java

我今天遇到了以下问题:我们有一个类Bar,其中有一个initBar()的实例。方法bar = new Bar()在类的生命周期的某个时刻(非常异步,有很多RxJava)被调用,它执行bar

现在,问题是我想在其他方法doStuff()中访问initBar(),但不能保证在bar之后调用该方法,所以{{1} }仍可以是null或已经存在。

如果bar已经存在,我想立即运行一个函数analyze(bar),如果它仍然null-我想安排它在设置bar后运行(作为initBar()通话的一部分)。

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

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

但是我觉得我在这里重塑轮子-当您要访问对象而不必担心它是否已设置时,可能存在针对此类问题的解决方案。是否应将其视为 Promise 并用CompletableFutureJDeferred完成?还是已经有一些不错的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
    ...
}

1 个答案:

答案 0 :(得分:0)

如果bar仅创建一次,请使用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
...
}