RX Java2处理异步超时异常

时间:2018-12-17 13:24:20

标签: java rx-java2

我正在做一些并发的io操作。下面的代码是针对我的体系结构的测试代码。我想给异步io操作超时,但是经过一些步骤后流程卡死了。当我放弃超时功能代码时,效果很好。

我想念的是什么?问题出在哪里?

    Scheduler mainObserveOn = Schedulers.from(Executors.newFixedThreadPool(1));
    Scheduler mainSubscribeOn = Schedulers.from(Executors.newFixedThreadPool(1));
    Scheduler flatmapObserveOn = Schedulers.from(Executors.newFixedThreadPool(2));
    Scheduler flatmapSubscribeOn = Schedulers.from(Executors.newFixedThreadPool(2));

    AtomicLong a = new AtomicLong();
    Flowable.create(emitter -> {

        while(true)
        {
            for (int i = 0; i < 100; i++)
            {
                emitter.onNext(a.incrementAndGet());
                System.out.println("Emit : "+a.get()+" | Thread : "+Thread.currentThread().getName());
            }

            Thread.sleep(100);
        }

    }, BackpressureStrategy.BUFFER)
    .observeOn(mainObserveOn)
    .flatMap(
            o -> Flowable.just(o)
                    .observeOn(flatmapObserveOn)
                    .doOnNext(o1 -> {
                        System.out.println(o1+" | Thread : "+Thread.currentThread().getName());

                        if( (long)o1 % 10 == 0 )
                        {
                            System.out.println("SLEEP");
                            Thread.sleep(10);
                        }
                    })
                    .doOnError(throwable -> throwable.printStackTrace())
                    .onExceptionResumeNext(s -> {})
                    .timeout(2, TimeUnit.MILLISECONDS)
                    .subscribeOn(flatmapSubscribeOn)
    )
    .subscribeOn(mainSubscribeOn)
    //.blockingSubscribe(System.out::println, System.err::println);
    .subscribe(System.out::println, System.err::println);


    Thread.sleep(1000000000000000000L);

通过我想跳过错误操作的方式,所以使用空的onExceptionResumeNext。有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

doOnNext()中的超时代码将导致观察者链每发射10睡眠10秒。稍后,您会有timeout() 2秒钟;这将在第十次发射时触发,导致发射onError()。此后您将没有错误处理代码,因此可能会导致整个观察者链退出。

结果将是初始排放量为101条记录线,随后的前10次排放量为10条记录线,后跟一条错误消息,可能为Timeout

尚不清楚您想发生什么,但这就是您所得到的。