繁体   English   中英

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

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

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

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

一个未来在一个线程上执行。 可能会在多个线程上执行几个期货。 因此,不超过一个未来可以同时占用一个线程。

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

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

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

注意:未来的处理程序,如Future{ ... }.map(handler)可以在与未来本身不同的线程中执行,但它实际上创建了另一个Future来获取结果。 flatMap 更确切地说,他们使用onComplete来创建CallbackRunnable以在旧的未来成功之后启动处理程序(可能在不同的线程中) - 这个回调刚刚完成了新创建的未来,所以仍然“每个未来不超过一个线程”

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

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

暂无
暂无

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

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