簡體   English   中英

為什么我的簡單scala對象在包含未來的同時會掛起一分鍾左右

[英]Why does my simple scala object hangs for a minute or so while it includes a 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")

}

當我按原樣運行程序時,輸出永遠不會打印

得到了回復

相反,看起來它會掛起一分鍾左右,而不會打印出預期的輸出。 我相信我在這里遺漏了一些非常基本的東西。

我也嘗試在最后添加System.in.read() ,當我輸入任何虛擬值時,程序結束打印預期結果。 這種行為背后的原因是什么? 有人可以幫我理解這個嗎?

如果沒有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)
  }
}

你需要等待未來,程序在完成之前就會退出。

import scala.concurrent.Await
import scala.concurrent.duration._

var myFuture = Future {
    Thread.sleep(1000)
    1
}

// oncomplete handlers, etc here

println(Await.result(myFuture, 5 seconds))

編輯:如果你必須使用onComplete並且無法驗證那些處理程序是否在Await.ready/result之前執行,那么你應該使用正式同步,即:

import scala.concurrent._
import java.util.concurrent.CountDownLatch

object Main extends App {
  val f = Future {
    Main.synchronized {
      Thread.sleep(1000);
      1
    }
  }

  val latch = new CountDownLatch(1)

  f.onComplete {
    case _ => { latch.countDown() }
  }

  latch.await()
}

嗯...因為你在未來的1000毫秒內睡覺,你的未來至少需要1秒才能完成。 應用程序線程自行完成並在此時退出。

在將來完成時,您必須確保應用程序線程處於活動狀態。 你可以通過在你的應用程序線程中休息一段時間來做到這一點......就像這樣。

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

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")
  }

  // Wait for some time
  // Not sure future will complete in this time or not
  Thread.sleep(1000);
  Thread.sleep(1000);
  Thread.sleep(1000);
}

但是,更好的方法是使應用程序線程需要未來完成。

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

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" )
  }

  while ( f.value == None ) {
    // Waste time just till the future is complete.
  }

  // Do something with future value.
  f.foreach( ( s: String ) => println( s ) )

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM