使用for循环并行执行scala期货
scala futures execution in parallel using for-loop
package p1
import scala.util.Failure
import scala.util.Success
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object modCheck extends App {
def getStudentRoolNo(name: String) = Future {
println("getStudentRoolNo")
name match {
case "name1" => 1
case "name2" => 2
case _ => throw new Exception("No doesnt exist")
}
}
def getRank(roolNo: Int) = Future {
println("getRank")
Thread.sleep(500)
roolNo match {
case 1 => "1"
case 2 => "2"
case _ => throw new Exception("No roolNo exist")
}
}
def getDetails(roolNo: Int) = Future {
println("getDetails")
roolNo match {
case 1 => "details 1"
case 2 => "Details 2"
case _ => throw new Exception("No details exist")
}
}
def getStudentRecord(name: String) = {
for {
rollNo <- getStudentRoolNo(name)
rank <- getRank(rollNo)
details <- getDetails(rollNo)
} yield (rank + details)
}
getStudentRecord("name1").onComplete {
case Success(ground) => println(s"got my Details $ground")
case Failure(ex) => println("Exception!" + ex)
}
Thread.sleep(2000)
}
我想在下面的代码中并行执行函数 getrank
和 getDetails
(一旦返回 getStudentRollNo
)。我怎样才能做到这一点?
我试了下面的方法,好像还是顺序执行的
请告诉我如何并行执行
Future 在创建时开始计算。
for (a <- x; b <- y) yield ???
被脱糖为 x.flatMap(a => y.map(b => ???))
flatMap()
和 map()
在 Future 完成后执行它的参数。
getDetails()
可以在 getRank()
完成之前开始,方法是分开创建 Future
和 flatMap()
调用。
for {
rollNo <- getStudentRoolNo(name)
rankFuture = getRank(rollNo)
detailsFuture = getDetails(rollNo)
rank <- rankFuture
details <- detailsFuture
} yield (rank + details)
正如您可能猜到的那样,您当前的代码不会并行调用 getRank 和 getDetails,因为它在内部进行了理解。它是 map
操作的语法糖。要实现并行性,您需要在 for-comprehension 之外创建两个 futures。
val student = getStudentRollNo(name)
val detailsFuture = student map {s => getRank(rollNo) }
val rankFuture = student map {s => getDetails(rollNo) }
for {
rank <- rankFuture
details <- detailsFuture
} yield (rank + details)
您可以在理解中使用 zip
来并行地 运行 两个 Futures:
def getStudentRecord(name: String) = {
for {
rollNo <- getStudentRoolNo(name)
rankRollNo <- getRank(rollNo) zip getDetails(rollNo)
} yield rankRollNo
}
上面的getRank
和getDetails
同时是运行,结果是一个字符串元组。如果要生成单个字符串,则需要将 rankRollNo
分成单独的组件:
yield rankRollNo._1 + rankRollNo._2
package p1
import scala.util.Failure
import scala.util.Success
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object modCheck extends App {
def getStudentRoolNo(name: String) = Future {
println("getStudentRoolNo")
name match {
case "name1" => 1
case "name2" => 2
case _ => throw new Exception("No doesnt exist")
}
}
def getRank(roolNo: Int) = Future {
println("getRank")
Thread.sleep(500)
roolNo match {
case 1 => "1"
case 2 => "2"
case _ => throw new Exception("No roolNo exist")
}
}
def getDetails(roolNo: Int) = Future {
println("getDetails")
roolNo match {
case 1 => "details 1"
case 2 => "Details 2"
case _ => throw new Exception("No details exist")
}
}
def getStudentRecord(name: String) = {
for {
rollNo <- getStudentRoolNo(name)
rank <- getRank(rollNo)
details <- getDetails(rollNo)
} yield (rank + details)
}
getStudentRecord("name1").onComplete {
case Success(ground) => println(s"got my Details $ground")
case Failure(ex) => println("Exception!" + ex)
}
Thread.sleep(2000)
}
我想在下面的代码中并行执行函数 getrank
和 getDetails
(一旦返回 getStudentRollNo
)。我怎样才能做到这一点?
我试了下面的方法,好像还是顺序执行的
请告诉我如何并行执行
Future 在创建时开始计算。
for (a <- x; b <- y) yield ???
被脱糖为 x.flatMap(a => y.map(b => ???))
flatMap()
和 map()
在 Future 完成后执行它的参数。
getDetails()
可以在 getRank()
完成之前开始,方法是分开创建 Future
和 flatMap()
调用。
for {
rollNo <- getStudentRoolNo(name)
rankFuture = getRank(rollNo)
detailsFuture = getDetails(rollNo)
rank <- rankFuture
details <- detailsFuture
} yield (rank + details)
正如您可能猜到的那样,您当前的代码不会并行调用 getRank 和 getDetails,因为它在内部进行了理解。它是 map
操作的语法糖。要实现并行性,您需要在 for-comprehension 之外创建两个 futures。
val student = getStudentRollNo(name)
val detailsFuture = student map {s => getRank(rollNo) }
val rankFuture = student map {s => getDetails(rollNo) }
for {
rank <- rankFuture
details <- detailsFuture
} yield (rank + details)
您可以在理解中使用 zip
来并行地 运行 两个 Futures:
def getStudentRecord(name: String) = {
for {
rollNo <- getStudentRoolNo(name)
rankRollNo <- getRank(rollNo) zip getDetails(rollNo)
} yield rankRollNo
}
上面的getRank
和getDetails
同时是运行,结果是一个字符串元组。如果要生成单个字符串,则需要将 rankRollNo
分成单独的组件:
yield rankRollNo._1 + rankRollNo._2