gpt4 book ai didi

multithreading - 是否使用 Future.successful 和 Future.failed 从执行上下文管理的线程池中请求一个线程

转载 作者:行者123 更新时间:2023-12-03 12:54:06 27 4
gpt4 key购买 nike

众所周知,在 Scala 中使用 Future 需要声明一个执行上下文,它会创建一个线程池,用于运行出现在 Future 中的代码。我的问题是,如果使用 Future.successful 或 Future.failed 会将此请求跳过到线程池。性能影响对于正确使用 Future 很重要。

为了提供一些背景知识,一位具有多年 Scala 经验的同事告诉我,不鼓励直接使用 Future() 来包装一些代码块,因为为了有意义,Future 调用中的代码必须有可能抛出异常,这是不可取的。在我们的代码库中,直接抛出异常被认为是非函数式的,并且还具有性能影响,因为抛出异常是一种相对较慢的操作,具有性能成本,因此应该避免。我的问题有两个部分:

1)我想知道避免直接调用 Future() 是否还有其他潜在影响:使用 Future.successful 和 Future.failed 是否通过不在线程池中调度线程上的工作来节省计算资源?通过创建一个已经完成的 Future,这两种编程结构是否避免了从线程池中请求线程?

具体来说,让我们比较两个代码块:

一种)

val fut = Future(1+1)



b)
val fut = Future.successful(1+1)

b) 是否通过不进入线程池来节省计算资源?

2)另外,我还想知道在映射或平面映射Future时是否从线程池请求线程。例如,我注意到任何涉及 Future 上的平面图的代码都需要定义执行上下文。这是否意味着平面图操作本身被安排在线程池中的线程上? Future 上的每个 map 或 flatmap 操作是否都发生在线程池中的线程上?在那种情况下,只要我们正在映射或平面映射 Future,即使由于使用 Future.successful 和 Future.failed 而已经完成,从线程池请求线程是否不可避免?

具体来说,让我们看一个例子:
val fut = Future.successful(1+1).map(x => x+1)

映射操作是否发生在从执行上下文管理的线程池中申请的线程内?

这只是为了让我更好地理解为什么使用 Future.successful 和 Future.failed 被认为比直接用 Future() 包装一些代码更好。重复我上面所说的,我已经知道抛出异常是一个性能瓶颈,但是使用 Future.successful 和 Future.failed 是否可以完全避免从线程池中请求线程,从而降低性能开销?这是否完全无关紧要,因为无论如何都必须在线程池中的线程上安排 future 的映射或平面映射?

最佳答案

Future.successfulFuture.failed不需要执行上下文,因此它们不会消耗任何线程。但是调用 map/flatMap/foreach在它们上确实需要传入回调的执行上下文,因此确实消耗了一个线程。不仅仅是性能方面的考虑,请调用 Future.successful(v)而不是 Future(v)适合在语义上表明我们已经有了值 v我们只是将其提升为 Future . Future.successful(1+1) 带来的性能提升而不是 Future(1+1)在真正的瓶颈将是慢 I/O(例如远程 API 调用、数据库查找等)的实际系统中可能可以忽略不计。

关于multithreading - 是否使用 Future.successful 和 Future.failed 从执行上下文管理的线程池中请求一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56763333/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com