【问题标题】:Scala Futures - keep main thread alive without explicitly setting time delayScala Futures - 在不显式设置时间延迟的情况下保持主线程存活
【发布时间】:2018-07-20 10:33:08
【问题描述】:

我第一次开始使用 Scala Futures。我对非阻塞(即不是Await.Result)解决方案感兴趣,以便在我运行一些异步数据库查询时保持我的主线程处于活动状态。使用到目前为止我找到的有关回调的信息,我整理了类似的内容。

def miniFuturesExample(conn: DatabaseConnection)
{
    val f1 = Future { runQuery(conn) }
    f1.onComplete
    {
        case Success(result) => println(result.next())
        case Failure(e) => e.printStackTrace()
    }
    // do some other stuff
    Thread.sleep(2000)
}

我希望避免为Thread.sleep 指定时间值。我不想硬编码的原因是因为我并不总是确定runQuery 方法需要多长时间才能完成。我想找到一个非阻塞解决方案来保持主线程处于活动状态,直到触发 f1onComplete 块。

【问题讨论】:

  • 在致电Await.Result 之前,您可以做任何您想做的事情,这听起来是sleep 的合理替代方案。您想避免阻塞的原因是什么?我也会调用 sleep 阻塞 - 当它处于睡眠状态时,你没有在线程上做任何事情。你能再展示一些你想同时执行的代码吗?
  • 我认为你在这里有一个根本的矛盾。你说你想要一个非阻塞的方式让主线程阻塞直到另一个线程完成。
  • 是的,你是对的 :)

标签: scala


【解决方案1】:

sleep 没有什么“非阻塞”的:) 如果你想让你的线程空闲直到异步任务完成,你必须阻塞它(这就是阻塞的意思)。 Await.result 正是你想要的。

或者,您可以设置一个监视器并在上面设置wait,例如:

 Future { runQuery(conn) }
   .onComplete { result => 
      result match {
         case Success(r) => println(r.next)
         case Failure(e) => e.printStackTrace()
      }
      synchronized { notifyAll }
   }

 synchronized { wait }

但实际上,它与Await.result 相同,只是更笨拙。

【讨论】:

    【解决方案2】:
    import scala.annotation.tailrec
    import scala.concurrent.Future
    import scala.concurrent.ExecutionContext.Implicits.global
    
    object WaitFuture {
      @tailrec
      def checkFutureComplete[T](f: => Future[T]): Unit = {
        if(f.isCompleted) ()
        else checkFutureComplete(f)
      }
    
      def main(args: Array[String]): Unit = {
      val k = Future {
        Thread.sleep(12000)
        println("Coming")
        10
      }
        checkFutureComplete(k)
        println(k)
        val k2 = k
        println(k2)
      }
    }
    //
    //Coming
    //Future(Success(10))
    //Future(Success(10))
    

    Future 是非阻塞和异步任务。只有当您在它们上Await 时,您才能转换(Future[T] => T)。正如@Dima 上面所发布的,这种方法也类似于 Await.result,我们在其中递归地检查未来的状态。即使我们检查了我们永远无法获得 T 值,但是没有Await,我们只能实现Future(Success(T))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 2013-08-20
      • 2020-11-15
      相关资源
      最近更新 更多