为什么我的简单scala对象在包含未来的同时会挂起一分钟左右

Jav*_*Man 2 concurrency scala future

我正在学习scala期货,我已经提出了我的问题.我有一个非常简单的例子

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.util.{Failure, Success}
/**
 * Created by dummy on 05/02/15.
 */
object FutureUtils extends App{

  val f = Future {
    Thread.sleep(1000)
    println("I am learning scala futures")
    "learning"
  }

  f onComplete {

    case Success(value:String) => println("got the response back")
    case Failure(t: Throwable) => println("did not expect this")

  }

  println("I am still learning")

}
Run Code Online (Sandbox Code Playgroud)

当我按原样运行程序时,输出永远不会打印

得到了回复

相反,看起来它会挂起一分钟左右,而不会打印出预期的输出.我相信我在这里遗漏了一些非常基本的东西.

我也尝试System.in.read()在最后添加,似乎当我输入任何虚拟值时,程序结束打印预期结果.这种行为背后的原因是什么?有人可以帮我理解这个吗?

Kim*_*bel 5

程序在没有它的情况下不起作用的原因System.in.read()onComplete在未来完成之前不会阻塞,而只是在它发生时添加回调.该回调永远不会被执行,因为整个程序在未来完成之前结束.要解决此问题,您可以故意让主线程进入无限循环并在回调中显式终止进程.

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._
import scala.util.{Failure, Success}

object Main extends App {
  val f = Future {
    Thread.sleep(1000)
    println("I am learning scala futures")
    "learning"
  }
  f onComplete {
    case Success(value:String) => println("got the response back"); System.exit(0)
    case Failure(t: Throwable) => println("did not expect this"); System.exit(1)
  }
  println("I am still learning")
  while (true){
    Thread.sleep(1000)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 另一种方法是使用对象`scala.concurrent.Await`中的`ready`或`result`方法等待`f`完成后再继续. (2认同)
  • 让我们只希望人们不要将这个建议扩展到任何真正的程序,其中上下文切换和睡眠线程占用的堆栈空间实际上很重要.可悲的是,正确的解决方案实际上更短,更容易理解. (2认同)