multithreadingscalaconcurrencyhtmlunitfuture

Are Futures executed on a single thread? (Scala)


Using the 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?

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. To do this, I would wrap each new WebClient instance in a Future. The only problem is that the WebClient class is not thread-safe, so I'm worried that it might break up and send to different threads.


Solution

  • 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 a task to your thread pool - this one task can't be implicitly parallelized so it's executed on one thread only. One or several tasks submitted to the pool are being put into the pool's queue, so the executor takes tasks from that queue one-by-one and runs each on some randomly (or intentionally) chosen threads. So several Futures may get to several threads.

    About shared objects - the only way to execute operations safely for an object shared between futures is using the Executors.newFixedThreadPool(1), which will use only one thread for the whole pool. Another solution - is to clone the object for every future. Using actors (make your shared object an actor's state) should be the best option.

    If you use one object per future - everything should be fine.

    Note: The future's handler, like Future{ ... }.map(handler) may be executed in a different thread than the future itself, but it actually creates another Future to obtain a result. Same for flatMap. More precisely, they use onComplete which creates a CallbackRunnable to launch the handler (possibly in a different thread) after the old future succeeds - this callback just completes the newly created future, so still "no more than one thread per future".