Multithreading 期货是在单个线程上执行的吗?(斯卡拉)

Multithreading 期货是在单个线程上执行的吗?(斯卡拉),multithreading,scala,concurrency,htmlunit,future,Multithreading,Scala,Concurrency,Htmlunit,Future,在Scala中使用默认的隐式执行上下文,是在单个专用线程上计算每个新的未来,还是将计算分割并分发到线程池中的多个线程 我不知道这是否有帮助,这个问题的背景是我想使用HTMLUnitAPI执行多个并发操作。为此,我将在将来包装每个新的WebClient实例。唯一的问题是WebClient类不是线程安全的,所以我担心它可能会被分解并发送到不同的线程。一个未来在单个线程上执行。可以在多个线程上执行多个未来。因此,一个线程最多只能同时占用一个未来 它是如何工作的?当您创建一个未来时,这意味着您已经将任务

在Scala中使用默认的隐式执行上下文,是在单个专用线程上计算每个新的未来,还是将计算分割并分发到线程池中的多个线程


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

一个未来在单个线程上执行。可以在多个线程上执行多个未来。因此,一个线程最多只能同时占用一个未来

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

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

如果你在将来使用一个对象,一切都会很好


注意:future的处理程序,如
future{…}.map(handler)
可能在future本身以外的线程中执行,但它实际上创建另一个
future
以获得结果。我也是。更准确地说,他们使用
onComplete
创建
CallbackRunnable
在旧的future成功后启动处理程序(可能在不同的线程中)-此回调只完成新创建的future,因此“每个future最多只能有一个线程”

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


至于第二个问题,只要每个将来都有一个实例,就不应该有任何并发性问题。

如果你所说的合成是指这样的东西——它们只是创建了一个新的成功的未来,没有正文(因此它根本不执行),然后添加处理程序(在合成中向将来添加处理程序)。因此,未来本身是在单线程中执行的;然而,处理程序(
Future.map
)可能在不同的处理程序中执行,但每个新的处理程序都返回不同的未来因此,序列只是产生了几个新的未来,但是没有一个未来可以被分配给多个线程。我指的是flatMap的使用或对未来的理解。这与
map
-创建一个处理程序并返回新的未来只是看一下谢谢!这正是我要找的信息。只是一个简单的后续问题——将多个未来提交给一个只有一个线程的新FixedThreadPool有什么好处?计算可以在单个线程上并发吗?根本没有性能优势。它唯一能给你的就是异步API(提交多个任务+完成后订阅)。您还可以为不同类型的未来创建多个池,但参与者在这方面做得更好。使用
implicit val ExecutionContext=ExecutionContext.fromExecutors.newFixedThreadPool(1)从
Executors创建
ExecutionContext