我似乎无法在Scala中的Promises上找到complete和tryComplete是否是原子操作的任何地方。仅应将承诺写入一次,但是例如,如果两个tryCompletes在两个不同的回调中同时发生,是否会出问题?还是我们保证tryComplete是原子的?
首先,请注意,success(...)
等同于调用complete(Success(...))
,tryComplete(...)
等同于complete(...).isCompleted
。
在文档中说
如前所述,promise具有单一分配语义。因此,它们只能完成一次。在已经完成(或失败)的promise上调用成功将引发IllegalStateException。
一个承诺只能完成一次。深入研究源代码,DefaultPromise
扩展了AtomicReference
(即线程安全),因此所有写操作都是原子的。这意味着,如果您有两个线程完成一个诺言,那么其中只有一个可以成功,而无论哪个先执行。另一个将抛出IllegalStateException
。
这里是一个小例子,说明您尝试两次完成诺言时会发生什么。
https://scastie.scala-lang.org/hTYBqVywSQCl8bFSgQI0Sg
尽管显然,似乎可以通过做一堆怪异的杂技来绕开Future
的不变性。
https://contributors.scala-lang.org/t/defaultpromise-violates-encapsulation/3440
一个人应该避免这种情况。