在RetryWhen中需要使用AtomicBoolean

时间:2018-11-04 09:44:01

标签: kotlin thread-safety rx-java rx-java2 reactivex

在Javadoc示例Observable.retryWhen中,AtomicInteger用于counter,而不是简单的常规Int。这真的有必要吗? errors在什么情况下可以在其他线程上发出?

我在阅读文档和资料时指出takeWhileflatMap闭包始终保证在同一线程上运行。

http://reactivex.io/RxJava/javadoc/io/reactivex/Observable.html#retryWhen-io.reactivex.functions.Function-

Observable.timer(1, TimeUnit.SECONDS)
     .doOnSubscribe(s -> System.out.println("subscribing"))
     .map(v -> { throw new RuntimeException(); })
     .retryWhen(errors -> {
         AtomicInteger counter = new AtomicInteger();
         return errors
                   .takeWhile(e -> counter.getAndIncrement() != 3)
                   .flatMap(e -> {
                       System.out.println("delay retry by " + counter.get() + " second(s)");
                       return Observable.timer(counter.get(), TimeUnit.SECONDS);
                   });
     })
     .blockingSubscribe(System.out::println, System.out::println);

1 个答案:

答案 0 :(得分:2)

这不是严格必要的,但是有些人看到一个用于计数器的元素int数组时会心脏病发作,因此AtomicInteger

 Observable.timer(1, TimeUnit.SECONDS)
 .doOnSubscribe(s -> System.out.println("subscribing"))
 .map(v -> { throw new RuntimeException(); })
 .retryWhen(errors -> {
     int[] counter = { 0 };
     return errors
               .takeWhile(e -> counter[0]++ != 3)
               .flatMap(e -> {
                   System.out.println("delay retry by " + counter[0] + " second(s)");
                   return Observable.timer(counter[0], TimeUnit.SECONDS);
               });
 })
 .blockingSubscribe(System.out::println, System.out::println);
  

在什么情况下错误可以在其他线程上发出?

处理程序序列可以具有其自己的线程,因此,只要您共享对可变状态的外部访问,就应确保访问是线程安全的。在该示例中,同样也没有必要,因为使用计数器期间的特定组合在单个线程上运行,并保证不会重叠自身,因为任何新错误都只能在当前序列发出重试信号后发生。 >