You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala无法获取Future结果,已尝试两种方案仍未解决求其他方法

Scala Future未执行完成的解决方案

你的代码里主线程(App特质的run方法线程)仅休眠5ms就结束,而默认global ExecutionContext使用的是守护线程,主线程结束后JVM会直接退出,导致Future任务还没执行完就被终止。

你尝试的两种方案无效的原因:

  • Await方案:大概率是代码写法错误——要么没替换掉原有的Thread.sleep(5),要么缺少scala.concurrent.duration._的导入导致Duration解析失败;如果只是在原有代码后追加Await,主线程可能已经执行到Thread.sleep(5)并触发App的sys.exit,Await根本没机会生效。
  • 自定义ExecutionContext方案:App特质在run方法执行完毕后会强制调用sys.exit(0),不管你有没有非守护线程,JVM都会直接退出,非守护线程的任务自然无法完成。

下面是几个有效的解决方法:

方法一:正确使用Await阻塞主线程

替换原有的休眠逻辑,用Await.result阻塞主线程直到Future任务完成,注意导入必要的包:

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

object Futures1 extends App {
  val f = Future {
    Thread.sleep(500)
    1 + 1
  }
  // 等待Future执行完成并打印结果
  Await.result(f.map(println), 5.seconds)
}

方法二:放弃App特质,自定义main方法

App特质的强制退出逻辑是问题核心,改用自定义main方法,配合非守护线程的ExecutionContext即可:

import scala.concurrent.{ExecutionContext, Future}

object Futures1 {
  class MyExecutionContext extends ExecutionContext {
    override def execute(runnable: Runnable): Unit = {
      val t = new Thread(runnable)
      t.setDaemon(false)
      t.start()
    }
    override def reportFailure(t: Throwable): Unit = t.printStackTrace()
  }

  implicit val context: ExecutionContext = new MyExecutionContext

  def main(args: Array[String]): Unit = {
    val f = Future {
      Thread.sleep(500)
      1 + 1
    }
    f.map(println)
    // 无需额外休眠,非守护线程会让JVM等待任务完成
  }
}

方法三:临时让主线程等待足够时间(仅调试用)

如果一定要保留App特质,也可以让主线程等待足够长的时间,确保Future任务完成(不推荐用于生产环境):

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

object Futures1 extends App {
  val f = Future {
    Thread.sleep(500)
    println(1 + 1)
  }
  // 等待时间需大于Future任务的耗时
  Thread.sleep(1000)
}

内容的提问来源于stack exchange,提问作者Jelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:23:15