Scala 如何运行返回Try的函数的并行实例?
我有一个函数,它返回一个Scala 如何运行返回Try的函数的并行实例?,scala,concurrency,Scala,Concurrency,我有一个函数,它返回一个Try,我想并行运行它的多个实例,但我对如何实现这一点一无所知–我似乎只能一个接一个地运行它。 上下文:此函数用于获取一个锁,以便在多个线程/工作线程并行运行时,它们不会互相读取。在测试中,我想同时运行五个实例,并断言除一个外,所有实例都被锁定。当函数返回一个Future时,这是有效的,但是我已经做了一些重构,现在它返回一个Try,测试已经停止工作 该行为似乎与锁定代码无关——似乎我不理解并发性 我一直在尝试使用Future.fromTry,并并行执行它们。例如: 导入
Try
,我想并行运行它的多个实例,但我对如何实现这一点一无所知–我似乎只能一个接一个地运行它。
上下文:此函数用于获取一个锁,以便在多个线程/工作线程并行运行时,它们不会互相读取。在测试中,我想同时运行五个实例,并断言除一个外,所有实例都被锁定。当函数返回一个Future时,这是有效的,但是我已经做了一些重构,现在它返回一个Try,测试已经停止工作
该行为似乎与锁定代码无关——似乎我不理解并发性
我一直在尝试使用
Future.fromTry
,并并行执行它们。例如:
导入scala.concurrent.ExecutionContext.Implicits.global
导入scala.concurrent.Future
导入scala.util.{Success,Try}
对象主应用程序{
def greet(名称:String):Try[Unit]=Try{
println(s“Hello$name!”)
线程。睡眠(1000)
println(s“再见$name!”)
()
}
Seq(“爱丽丝”、“鲍勃”、“卡罗尔”、“戴夫”、“伊芙”).map{name=>
Future.fromTry{greet(name)}
}
}
我希望看到所有的“你好”消息,然后是所有的“再见”消息——相反,它似乎在一个接一个地执行它们
你好,爱丽丝!
再见,爱丽丝!
你好,鲍勃!
再见,鲍勃!
你好,卡罗尔!
再见,卡罗尔!
你好,戴夫!
再见,戴夫!
你好,伊芙!
再见,伊芙!
我环顾四周,发现了关于调整ExecutionContext和添加并行性的建议——事实是,这个环境似乎非常乐意并行运行Futures
在同一台机器上,使用相同的全局ExecutionContext,如果我调整函数以返回未来,而不是尝试,我会看到预期的输出,并且函数看起来是并行运行的
导入scala.concurrent.ExecutionContext.Implicits.global
导入scala.concurrent.Future
导入scala.util.{Success,Try}
对象主应用程序{
def greet(名称:字符串):Future[单位]=Future{
println(s“Hello$name!”)
线程。睡眠(1000)
println(s“再见$name!”)
()
}
Seq(“费思”、“格雷斯”、“海蒂”、“伊凡”、“朱迪”).map{name=>
问候(姓名)
}
Thread.sleep(2000)//让未来完成
}
费思你好!
你好,伊万!
你好,格雷斯!
你好,朱迪!
你好,海蒂!
再见,伊万!
再见,格雷斯!
再见,海蒂!
再见,朱迪!
再见,费斯!
我对未来做了什么错事。fromTry
这意味着它正在等待未来的结束?如何使其与第二个示例相匹配
还是我完全找错了树了?明确指出,fromTry
将根据结果创建一个已经完成的未来,因此它首先评估函数,然后在未来上下文中提升它。因此,它是完全连续的
您可以首先从名称创建一个列表[Future[String]]
,然后映射列表和内部未来以执行您的功能。或者,既然未来已经代表了失败的可能性(并且在内部使用Try),为什么不在你的函数中简单地使用未来(就像你之前说的那样)。@LuisMiguelMejíaSuárez这比我想象的要简单,现在我觉得很傻。完成后,不用担心,混乱会发生,因为未来是急切的,如果他们是懒惰的(比如
IO
,Task
或ZIO
),这将产生预期的结果。顺便说一句,如果你觉得你的问题可能太简单了,那么你可以试着换个方式问。