Scala 中的异步 IO 与 future

2023-12-24

假设我正在从某些 URL 获取要下载的(可能很大)图像列表。我正在使用 Scala,所以我会做的是:

import scala.actors.Futures._

// Retrieve URLs from somewhere
val urls: List[String] = ...

// Download image (blocking operation)
val fimages: List[Future[...]] = urls.map (url => future { download url })

// Do something (display) when complete
fimages.foreach (_.foreach (display _))

我对 Scala 有点陌生,所以这对我来说仍然有点像魔法:

  • 这是正确的做法吗?如果不是的话还有其他选择吗?
  • 如果我有 100 个图像要下载,这会立即创建 100 个线程,还是会使用线程池?
  • 最后一条指令(display _)在主线程上执行,如果不是,我如何确定它是?

谢谢你的建议!


在 Scala 2.10 中使用 Future。它们是 Scala 团队、Akka 团队和 Twitter 之间的联合工作,旨在实现更标准化的未来 API 和跨框架使用的实现。我们刚刚在以下位置发布了指南:http://docs.scala-lang.org/overviews/core/futures.html http://docs.scala-lang.org/overviews/core/futures.html

除了完全非阻塞(默认情况下,尽管我们提供了执行托管阻塞操作的能力)和可组合性之外,Scala 2.10 futures 还带有一个隐式线程池来执行任务,以及一些管理超时的实用程序。

import scala.concurrent.{future, blocking, Future, Await, ExecutionContext.Implicits.global}
import scala.concurrent.duration._

// Retrieve URLs from somewhere
val urls: List[String] = ...

// Download image (blocking operation)
val imagesFuts: List[Future[...]] = urls.map {
  url => future { blocking { download url } }
}

// Do something (display) when complete
val futImages: Future[List[...]] = Future.sequence(imagesFuts)
Await.result(futImages, 10 seconds).foreach(display)

上面,我们首先导入了一些东西:

  • future:创造未来的API。
  • blocking:用于托管阻塞的API。
  • Future:Future 伴随对象,其中包含许多有用的方法收藏品期货。
  • Await:用于阻塞未来的单例对象(将其结果传输到当前线程)。
  • ExecutionContext.Implicits.global:默认的全局线程池,一个ForkJoin池。
  • duration._:用于管理超时持续时间的实用程序。

imagesFuts与您最初所做的大致相同 - 这里唯一的区别是我们使用托管阻塞 -blocking。它通知线程池您传递给它的代码块包含长时间运行或阻塞操作。这允许池暂时生成新的工作人员,以确保永远不会发生所有工作人员都被阻塞的情况。这样做是为了防止阻塞应用程序中的饥饿(锁定线程池)。请注意,线程池还知道托管阻塞块中的代码何时完成,因此它将删除此时的空闲工作线程,这意味着池将缩小回其预期大小。

(如果你想绝对阻止创建额外的线程,那么你应该使用 AsyncIO 库,例如 Java 的 NIO 库。)

然后我们使用Future伴生对象的集合方法来转换imagesFuts from List[Future[...]] to a Future[List[...]].

The Await对象是我们如何确保display在调用线程上执行--Await.result只是强制当前线程等待,直到它传递的未来线程完成。 (这在内部使用托管阻塞。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 中的异步 IO 与 future 的相关文章

  • “原子”系统调用是什么意思?

    我知道atomic通常在以下上 下文中使用竞争条件意思是类似一致性 and 根据多线程 多处理环境确定结果 没关系 但最近我读到了Linux中的原子系统调用 但不明白什么是atomic实际上这里的意思是 即how this 原子性 is 实
  • 在 Scala 中定义具有多个隐式参数的函数

    如何定义具有多个隐式参数的函数 def myfun arg String implicit p1 String implicit p2 Int doesn t work 它们必须全部放入一个参数列表中 并且该列表必须是最后一个 def my
  • Scala 中简单表达式的非法开始

    我刚刚开始学习scala 在尝试实现递归函数时 我在 Eclipse 中收到错误 简单表达式的非法开始 def foo total Int nums List Int if total nums sorted head 0 0 else r
  • 抽象类型与类型参数

    在什么情况下抽象类型应该优先于类型参数 添加到我的之前关于抽象类型与参数的回答 https stackoverflow com questions 1154571 scala abstract types vs generics 11547
  • Haskell 中的 Monad 和 Purity

    我的问题是 Haskell 中的 monad 是否真正保持了 Haskell 的纯度 如果是的话 又是如何保持的 我经常读到副作用是如何不纯粹的 但有用的程序 例如 I O 需要副作用 下一句指出 Haskell 对此的解决方案是 mona
  • Scala 中的 Case 对象与枚举

    是否有关于何时使用的最佳实践指南案例类 http en wikipedia org wiki Scala 28programming language 29 Case classes and pattern matching 或 case
  • Scala Spark:将数据框中的双列转换为日期时间列

    我正在尝试编写代码来将日期时间列 date 和 last updated date 转换为 mm dd yyyy 格式以进行显示 它们实际上是 unix 时间转换为双精度数 我该怎么做呢 import org joda time impor
  • 在 Scala REPL 中访问包私有方法

    假设我有一个private stuff method Stuff something in org my stuff 我可以在 Scala REPL 中做些什么 以便我可以调用Stuff something没有得到错误error value
  • Python 多处理进程在一段时间后休眠

    我有一个脚本 它运行一个目录 并搜索具有给定结尾 即 xml 的所有文件以查找给定字符串并替换它们 为了实现这一点 我使用了 python 多处理库 作为示例 我使用 1100 个 xml 文件 其中包含大约 200MB 的数据 在我的 M
  • 多线程归并排序,添加额外的线程

    我在java中的多线程合并排序算法中面临一个问题 我应该将代码修改为 3 4 5 6 7 8 线程合并排序 将原始数组划分为subArrays 目前它有2subArrays 如何将原始数组拆分为 3 4 5 6 7 8subArray是为了
  • 如何在 Python 中使用线程?

    我想要一个清晰的示例 显示任务被划分到多个线程中 自从 2010 年提出这个问题以来 如何使用 Python 进行简单的多线程处理已经有了真正的简化map https docs python org 2 library functions
  • 特征/类类型参数优先于方法类型参数的规则是什么

    我已经使用 scala 一段时间了 我认为我真的开始理解一切 好吧 大多数事情 但我发现自己对 Map 类中的许多方法定义感到困惑 我知道 FoldLeft 等如何工作 但我感到困惑的是 Map 函数中使用的类型参数 我们以 FoldLef
  • 减少最大值并保存其索引

    int v 10 2 9 1 3 5 7 1 2 0 0 int maximo 0 int b 0 int i pragma omp parallel for shared v private i reduction max maximo
  • 如何在 Scala 中跳过可选参数?

    给定以下带有可选参数的函数 def foo a Int 1 b Int 2 c Int 3 我想保留默认值a但将新值传递给b and c仅通过位置赋值 而不是通过命名赋值 即以下任何语法都可以 foo 5 7 foo 5 7 Scala 可
  • Flask 从线程中删除会话变量

    我尝试实施投票系统 它的工作原理是这样的 如果用户对帖子进行投票 我会在会话变量中记录其临时状态 已投票 已加星标等 如果当前用户在我将结果保存到临时表之前尚未投票 用户可以在 5 分钟内更改投票 5 分钟后 结果将使用线程永久写入数据库
  • 多线程:您在什么时候创建了太多线程?

    我正在开发一个多线程应用程序 该应用程序最初是单线程 后来扩展到多线程以实现性能提升 我有一个主线程 它将工作分成更小的块 并将其卸载到处理这些块的工作线程 此部分使用信号量进行控制 以在任何时间仅允许 X 个工作线程 工作线程生成数据块
  • 如何实现具有LinkedHashMap类似功能的ConcurrentHashMap?

    我用过LinkedHashMap with accessOrdertrue 并同时允许最多 500 个条目作为数据的 LRU 缓存 但由于可扩展性问题 我想转向一些线程安全的替代方案 ConcurrentHashMap在这方面似乎不错 但缺
  • “read”和“sysread”有什么区别?

    read http perldoc perl org functions read html and sysread http perldoc perl org functions sysread html有非常相似的文档 两者有何区别 A
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 将数组中的值提取到元组中

    有没有一种简单的方法可以将列表的值提取到 Scala 中的元组中 基本上是这样的 15 8 split map toInt mkTuple 15 8 或者我可以采取其他方式 val x y 15 8 split map toInt 如果你把

随机推荐

  • spring hibernate乐观锁问题

    这是我的存储库层 class RepositoryImpl implements Repository Override public Serializable saveOrUpdate Object obj return getSessi
  • Node.js 加密密钥和 iv 匹配 java SecretKeySpec / IvParameterSpec

    我正在尝试将 Java 简单 加密算法移植到 Node JS 我需要能够解密 加密从 Java 端加密 解密的内容 我被困在一开始 密码的初始化 在Java中 我得到了密钥SecretKeySpec 以及初始化向量IvParameterSp
  • 当 RabbitMQ 消费者崩溃时,获取的消息会发生什么情况?

    如果我有一个 RabbitMQ 消费者批量检索 100 条消息 但在将这些消息标记为已处理之前它就崩溃了 那么这些消息是否丢失了 我希望队列中的每条消息至少被处理一次 处理在确认消息之前崩溃的消费者的推荐方法是什么 RabbitMQ 是否以
  • 如何动态更改 clr-icon 自定义元素的形状?

    In the 清晰度图标文档 https vmware github io clarity icons how to use它们表明您可以使用 shape 属性来设置图标形状 如下所示
  • 自动添加和删除成员的聊天 API [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在和一个使用 telegram 应用程序发送足球比赛投注提示的人合作 他希望该群组是私有的 现在他
  • Docker如何共享资源

    我一直在研究 Docker 我从中了解到这个帖子 https stackoverflow com questions 16047306 how is docker io different from a normal virtual mac
  • Python 请求响应解码

    我使用 python requests 发送请求 然后打印响应 令我困惑的是响应中的中文字符类似于 u6570 u636e u8fd4 u56de u6210 u529f这是代码 coding utf 8 import requests u
  • 如何更改flutter包的java版本?

    我正在我的 flutter 项目的包中编辑 java 文件 但它是使用源 1 7 构建的 我该如何更改它 Flutter Channel dev 1 27 0 8 0 pre on Microsoft Windows Version 10
  • 使用 React 中的函数打开外部链接

    我正在尝试在 React 中创建一个按钮 该按钮打开指向谷歌地图网址的外部链接 我有一个函数询问用户的地理位置 一旦提供 就会将位置输入到 url 链接中 该链接获取从其地理位置到设定目的地的方向 但是 我正在努力让按钮首先运行该函数并在n
  • 测试协议与相关类型的一致性

    我有一个使用关联类型的协议 如下所示 protocol Populatable typealias T func populateWith object T 以及实现该协议的类 class DateRowType Populatable f
  • 如果我使用提供程序,如何在应用程序启动时调用方法?

    我想完成get请求服务器在启动时获取我的应用程序的数据 我阅读了几个描述如何在构建小部件后运行方法的主题 但所有这些都描述了当provider没有使用 我不确定在小部件内执行此请求是否是个好主意 我尝试了几种方法但没有成功 这是我的代码 v
  • vim中的相对数

    我注意到 vim 中关于相对数字的奇怪行为 set nu 1 2 3 4 5 6 设置相对编号 2 1 3 1 2 3 设置诺努 2 1 0 1 2 3 我问自己为什么有时我看到绝对当前行号 有时我看到 0 这是非常无用的 这种行为正常吗
  • HTTP 标头值中允许使用哪些字符?

    学习后HTTP 1 1标准 https www ietf org rfc rfc2616 txt 特别是第 31 页和相关内容 我得出的结论是任何 8 位八位字节都可以出现在 HTTP 标头值中 IE 代码在 0 255 范围内的任何字符
  • BouncyCastle .NET 自定义 TlsClient,适用于 Android 上运行的匿名 CipherSuite,但不适用于 Windows

    我可以访问一个使用 CipherSuite 的 java 应用程序TLS ECDH anon WITH AES 256 CBC SHA用于通信 不可能使用另一个 前段时间 我不得不用 C 编写一个 Xamarin 应用程序 它使用 Boun
  • Git 恢复错误消息?

    在尝试恢复我对 emacs d 文件夹的存储库所做的提交时 我收到以下消息 haziz haziz gt git revert 7fe3f error could not revert 7fe3f0b emacs d contents fr
  • 顺序等待 VS 连续等待

    我想知道编写由两个 或多个 异步和依赖 第一个必须完成才能执行第二个 操作组成的异步代码的最佳 正确方法是什么 异步 等待示例 await RunFirstOperationAsync await RunSecondOperationAsy
  • 接口静态初始化

    当我尝试写这样的东西时 public interface MyInterface static System out println Hello 编译器无法编译它 但是当我写下这样的东西时 interface MyInterface Int
  • mySQL - 使用 PHP 的 mysqli 设置隔离级别

    如何使用 mysqli 在 PHP 中将事务的隔离级别设置为 SERIALIZABLE 我到处都找过了 但找不到任何相关信息 Here http www learn mysql tutorial com Transactions cfm是对
  • 为什么未使用react-hook-form在Material UI Autocomplete中设置初始值?

    我在用react hook form https react hook form com https react hook form com 在我的演示中 我无法设置默认值AutoComplete 我已经尝试过了defaultValue正如
  • Scala 中的异步 IO 与 future

    假设我正在从某些 URL 获取要下载的 可能很大 图像列表 我正在使用 Scala 所以我会做的是 import scala actors Futures Retrieve URLs from somewhere val urls List