Future 是单线程执行的吗? (斯卡拉)

Are Futures executed on a single thread? (Scala)

在 Scala 中使用默认的隐式执行上下文,每个新的 future 是在单个专用线程上计算还是将计算划分并分配给线程池中的多个线程?

我不知道这是否有帮助,这个问题的背景是我想使用 HtmlUnit API 执行多个并发操作。为此,我会将每个新的 WebClient 实例包装在 Future 中。唯一的问题是 WebClient class 不是线程安全的,所以我担心它可能会中断并发送到不同的线程。

一个未来在单个线程上执行。多个期货可能会在多个线程上执行。所以,最多只能有一个future同时占用一个线程。

它是如何工作的?当您创建一个 Future 时,这意味着您已经将任务提交给您的线程池——这个任务不能隐式并行化,因此它只在一个线程上执行。提交给池的一个或多个任务被放入池的队列中,因此执行者从该队列中一个接一个地获取任务,并且 运行 每个随机(或有意)选择的线程。所以几个Futures可能会到几个线程。

关于共享对象 - 为 futures 之间共享的对象安全执行操作的唯一方法是使用 Executors.newFixedThreadPool(1),它将只为整个池使用一个线程。另一个解决方案 - 是为每个未来克隆这样的对象。使用 actor(让你的共享对象成为 actor 的状态)应该是最好的选择。

如果每个未来使用一个对象 - 一切都应该没问题。

注意:未来的处理程序,如 Future{ ... }.map(handler) 可能在与未来本身不同的线程中执行,但它实际上创建另一个 Future 以获得结果。 flatMap 也一样。更准确地说,他们使用 onComplete 创建 CallbackRunnable 在旧的未来成功之后启动处理程序(可能在不同的线程中) - 这个回调刚刚完成新创建的未来,所以仍然 "no more than one thread per future"

一个Future[+T]如果它由多个future组成,则不能保证它会在同一个线程上完成。也就是说,这并不意味着您会得到并发修改异常或类似的东西。您仍然可以让异步代码按顺序执行,在这种情况下它是安全的。

关于你的第二个问题,只要每个未来都有一个实例,你就不应该有任何并发​​问题。