Завершение гонки обещаний scala - PullRequest
2 голосов
/ 02 мая 2020

Кажется, я нигде не могу найти, являются ли complete и tryComplete атомами c операций над Promises в Scala. Обещания должны быть записаны только один раз, но если два tryComplete происходят одновременно в двух разных обратных вызовах, например, может что-то не так go? Или мы уверены, что tryComplete является атомом c?

1 Ответ

2 голосов
/ 02 мая 2020

Сначала быстрое примечание, что success(...) эквивалентно вызову complete(Success(...)), а tryComplete(...) эквивалентно complete(...).isCompleted.

В документах написано

Как Как упоминалось ранее, обещания имеют семантику с одним назначением Таким образом, они могут быть завершены только один раз. В случае успешного вызова для обещания, которое уже выполнено (или не выполнено), возникнет исключение IllegalStateException.

Обещание может быть выполнено только один раз. Копаясь в исходном коде, DefaultPromise расширяет AtomicReference (ie. Потокобезопасен), и поэтому все записи являются атомами c. Это означает, что если у вас есть два потока, выполняющих обещание, только один из них может когда-либо преуспеть, и это произойдет в зависимости от того, что было первым. Другой бросит IllegalStateException.

Вот небольшой пример того, что происходит, когда вы дважды пытаетесь выполнить обещание.

https://scastie.scala-lang.org/hTYBqVywSQCl8bFSgQI0Sg

Хотя, по-видимому, кажется, что можно обойти неизменность Future, выполнив кучу странных акробатических заклинаний.

https://contributors.scala-lang.org/t/defaultpromise-violates-encapsulation/3440

Вероятно, следует избегать что.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...