如何正确使用 Scala Futures?

How to use Scala Futures the right way?

我想知道 Futures 是否最好只与 Actors 一起使用,而不是在不使用 Actor 的程序中使用。换句话说,使用未来执行异步计算是否应该在 Actors 系统中更好地完成?

我为什么这么说:

1 - 您执行的计算结果会触发您可能在另一个线程中执行的某些操作。

例如,我有一个很长的操作来确定某物的价格,从我的主线程,我决定为它启动一个异步进程。与此同时,我可以做其他事情,然后当响应是 ready/availble 或与我沟通时,我会继续那条路。

我可以看出对于 actor 这很方便,因为您可以将结果通过管道传递给 actor。但是对于典型的线程模型,您可以阻塞或.... ?

2 - 另一个问题,假设我需要通过在线获取一些信息来更新参与者列表的年龄。假设我只有一个未来来完成这项任务。关闭参与者列表不是做错了什么。多个线程可能同时访问该参与者列表。因此,在未来进行更新将是错误的,在这种情况下,我们需要 java 并发收集,不是吗?

Maybe i see it the wrong way, future are not meant to do side effect at all

但那样的话,很公平,没有副作用,但我们仍然有从调用线程取回值的问题,这只能是阻塞的。我的意思是让我们想象一下,结果会帮助调用线程更新一些数据结构。如何在不以某种方式关闭该数据结构的情况下异步进行更新。

I believe the call backs such as OnComplete can be use for side-effecting (Am it right here?)

不过,无论如何,回调都必须关闭数据结构。因此我不明白如何不使用 Actor。

PS:我喜欢演员,我只是想更好地理解没有演员的未来的用法。我到处都读到,只有在需要管理状态时才应该使用演员。在我看来,总的来说,如果结果需要在某个时间点传回给发起异步任务的线程,那么在没有 actor 的情况下使用 future 总是会在某处阻塞。

Actor 在处理 可变状态 时非常有用,因为它们封装了可变状态。并且只允许基于消息的交互。

您可以使用Future在不同的线程中执行。您不必阻塞 Future,因为 Scala 的 Future 组合。因此,如果您的代码中有多个 Future,则不必 wait/block 让所有 Future 都参与竞争。例如,如果您的管道是完全非阻塞的或异步的(例如,Play 和 Spray),您可以 return 将 Future 返回给客户端。

与 Actor 相比,Future 是轻量级的,因为您不需要完整的 Actor 系统。

这是我非常喜欢的 Martin Odersky 的一句话。

There is no silver bullet for all concurrency issues; the right solution depends on what one needs to achieve. Do you want to define asynchronous computations that react to events or streams of values? Or have autonomous, isolated entities communicating via messages? Or define transactions over a mutable store? Or, maybe the primary purpose of parallel execution is to increase the performance? For each of these tasks, there is an abstraction that does the job: futures, reactive streams, actors, transactional memory, or parallel collections.

因此,请根据您的用例和需求选择您的抽象。