Сначала быстрое примечание, что 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
Вероятно, следует избегать что.