Использование AtomicBoolean требуется в RetryWhen - PullRequest
0 голосов
/ 04 ноября 2018

В примере Javadoc Observable.retryWhen, AtomicInteger используется для counter вместо простого обычного Int. Это действительно необходимо? При каких обстоятельствах errors может излучать в другом потоке?

Мое чтение документов и источника показывает, что закрытия takeWhile и flatMap всегда гарантированно работают в одном потоке.

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 голосов
/ 04 ноября 2018

Это не является строго необходимым, но у некоторых случается сердечный приступ, когда они видят для счетчика массив из одного элемента 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);

При каких обстоятельствах могут возникать ошибки в другом потоке?

Последовательность обработчика может иметь свою собственную многопоточность, поэтому всякий раз, когда у вас есть общий внешний доступ к изменяемому состоянию, вы должны быть уверены, что доступ к нему является потокобезопасным. В этом примере, опять же, это не является необходимым, так как конкретная комбинация во время использования счетчика выполняется в одном потоке и гарантированно не перекрывает себя, поскольку любая новая ошибка может произойти только после того, как текущая последовательность дала сигнал о повторной попытке.

...