简体   繁体   English

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

[英]Are Futures executed on a single thread? (Scala)

Using the default implicit execution context in Scala, will each new future be computed on a single, dedicated thread or will the computation be divided up and distributed to multiple threads in the thread pool? 使用Scala中的默认隐式执行上下文,是否会在单个专用线程上计算每个新的未来,还是将计算划分并分发到线程池中的多个线程?

I don't know if this helps, the background to this question is that I want to perform multiple concurrent operations using the HtmlUnit API. 我不知道这是否有帮助,这个问题的背景是我想使用HtmlUnit API执行多个并发操作。 To do this, I would wrap each new WebClient instance in a Future. 为此,我将每个新的WebClient实例包装在Future中。 The only problem is that the WebClient class is not thread safe, so I'm worried that it might broken up and sent to different threads. 唯一的问题是WebClient类不是线程安全的,所以我担心它可能会被分解并发送到不同的线程。

One future is executed on a single thread. 一个未来在一个线程上执行。 Several futures might be executed on several threads. 可能会在多个线程上执行几个期货。 So, no more than one future can occupy one thread simultaneously. 因此,不超过一个未来可以同时占用一个线程。

How does it work? 它是如何工作的? When you create a Future it means that you've submitted task to your thread-pool - this one task can't be implicitly parallelized so it's executed on one thread only. 当您创建Future时,它意味着您已将任务提交到您的线程池 - 这个任务不能被隐式并行化,因此它只在一个线程上执行。 One or several tasks submitted to the pool are being put into pool's queue, so executor takes tasks from that queue one-by-one and run each on some randomly (or intentionally) chosen thread. 提交到池的一个或多个任务被放入池的队列中,因此执行器逐个从该队列中获取任务,并在一些随机(或有意)选择的线程上运行每个任务。 So several Futures may get to several threads. 所以几个期货可能会涉及多个线程。

About shared object - the only way to execute operations safely for object shared between futures is using Executors.newFixedThreadPool(1) , it will use only one thread for the whole pool. 关于共享对象 - 对于期货之间共享的对象安全执行操作的唯一方法是使用Executors.newFixedThreadPool(1) ,它将只使用整个池的一个线程。 Another solution - is to clone such object for every future. 另一个解决方案 - 是为每个未来克隆这样的对象。 Using actors (make your shared object an actor's state) should be the best option. 使用actor(使您的共享对象成为actor的状态)应该是最佳选择。

If you use one object per future - everything should be fine. 如果你每个未来都使用一个对象 - 一切都应该没问题。

Note: The future's handler, like Future{ ... }.map(handler) may be executed in different thread than the future itself, but it actually creates another Future to obtain a result. 注意:未来的处理程序,如Future{ ... }.map(handler)可以在与未来本身不同的线程中执行,但它实际上创建了另一个Future来获取结果。 Same for flatMap . flatMap More precisely, they use onComplete which creates CallbackRunnable to launch handler (possible in different thread) after old future's success - this callback just completes newely created future, so still "no more than one thread per future" 更确切地说,他们使用onComplete来创建CallbackRunnable以在旧的未来成功之后启动处理程序(可能在不同的线程中) - 这个回调刚刚完成了新创建的未来,所以仍然“每个未来不超过一个线程”

A Future[+T] cannot guarantee that it will be completed on the same thread if its composed of multiple futures. Future[+T]不能保证如果它由多个期货组成,它将在同一个线程上完成。 That said, it doesn't mean that you'll get a concurrent modification exception or something along those lines. 也就是说,这并不意味着你会得到一个并发修改异常或类似的东西。 You can still get asynchronous code to execute sequentially, in which case it would be safe. 你仍然可以获得顺序执行的异步代码,在这种情况下它是安全的。

As for your second question, as long as you have one instance for each future you shouldn't have any concurrency issues. 至于你的第二个问题,只要你有一个每个未来的实例,你不应该有任何并发​​问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM