帮助解释scala future的2个现象(在代码4& code5中加粗),谢谢。
代码1
package com.tst
import akka.actor.{Actor, ActorSystem, Props}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class MyActor extends Actor {
def receive = {
case _ =>
for (i <- 1 to 6) {
Future {
println("start")
Thread.sleep(30000)
println("end")
}
}
}
}
object Test extends App {
val system = ActorSystem()
val myActor = system.actorOf(Props[MyActor])
myActor ! 'msg
}
对于code1,因为我的cpu核心是4,所以在最初的30秒,我们只能看到4 start
打印,对我来说没问题。 (如果你的cpu有更多核心,例如8核心,你可以将循环从6改为10来重现我的问题)
代码2
package com.tst
import akka.actor.{Actor, ActorSystem, Props}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, blocking}
class MyActor extends Actor {
def receive = {
case _ =>
for (i <- 1 to 6) {
Future {
blocking {
println("start")
Thread.sleep(30000)
println("end")
}
}
}
}
}
object Test extends App {
val system = ActorSystem()
val myActor = system.actorOf(Props[MyActor])
myActor ! 'msg
}
对于code2,当添加blocking
时,会使用其他线程,因此我们最初可以看到6 start
打印,对我来说没问题。
CODE3
package com.tst
import akka.actor.{Actor, ActorSystem, Props}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, blocking}
class MyActor extends Actor {
def receive = {
case _ =>
for (i <- 1 to 6) {
Future {
blocking { // lineA
println("startpre")
Thread.sleep(30000)
println("endpre")
}
}
}
Thread.sleep(2000)
for (i <- 1 to 6) {
println("+")
Future {
blocking { // lineB
println("start")
Thread.sleep(30000)
println("end")
}
}
}
}
}
object Test extends App {
val system = ActorSystem()
val myActor = system.actorOf(Props[MyActor])
myActor ! 'msg
}
对于code3,我们可以看到6 startpre
&amp; 6 start
打印最初30秒,对我来说没问题。
码4
只需删除code3中的lineA,输出为:
startpre
startpre
startpre
startpre
+
+
+
+
+
+
这是我的第一个问题:为什么我可以在最初的30秒内看到4 startpre
?为什么lineB中的blocking
不起作用?根据我的理解,我还应该看到6 start
代码4
只需删除code3 for code3,如果在code4中删除它,请记得取消删除lineA,输出为:
startpre
startpre
startpre
startpre
startpre
startpre
+
+
+
+
+
+
start
这是我的第二个问题:这里有1 start
被看到,但是所有4个线程都已被占用,并且为lineA的Future启动了2个额外的线程,为什么还剩下一个线程for lineB打印1 start
?
答案 0 :(得分:2)
Here我的观点很好。
将部分代码放在blocking
通知执行上下文中,可能需要一些其他线程结果来完成此阻塞。因此,运行另一个线程来完成加速评估是合理的。
换句话说,在你的情况code4
4个线程忙于从第一个循环执行Futures
,它们没有标记为blocking
所以没有理由在池中添加另一个工作线程,所以,没有线程可以从第二个循环中执行任何新的Future
。
在code5
中,所有帖子都忙于Future
标记为blocking
。其他线程已启动,在没有Future
的情况下从另一个循环中占用blocking
,因此没有理由再添加一个线程。