完成 Scala Promises 竞赛

Completing scala promises race

我似乎无法在任何地方找到 complete 和 tryComplete 是否是 Scala 中 Promises 的原子操作。 Promises 应该只被写入一次,但是如果两个 tryCompletes 在两个不同的回调中同时发生,那么会不会出现问题?还是我们确信 tryComplete 是原子的?

首先快速说明 success(...) 相当于调用 complete(Success(...))tryComplete(...) 相当于 complete(...).isCompleted

文档中说

As mentioned before, promises have single-assignment semantics. As such, they can be completed only once. Calling success on a promise that has already been completed (or failed) will throw an IllegalStateException.

一个承诺只能完成一次。深入研究源代码,DefaultPromise 扩展了 AtomicReference(即线程安全),因此所有写入都是原子的。这意味着如果你有两个线程完成一个承诺,那么只有其中一个可以成功,而且它会先完成。另一个会抛出 IllegalStateException.

这里有一个小例子,说明当您尝试完成一个承诺两次时会发生什么。

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

虽然很明显似乎可以通过一些奇怪的转换技巧来规避 Future 的不变性。

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

人们应该避免这种情况。