2015-01-26 17 views
13

Bằng cách thực thi mã scala này, tôi không có bất kỳ đầu ra nào trong bảng điều khiển. (Tôi thực sự không hiểu điều gì đang xảy ra)Sử dụng tương lai và Thread.sleep

Nếu tôi xóa Console.println("Console.println OK!") => mọi thứ có vẻ ổn.

Nếu tôi xóa Thread.sleep(2000) => mọi thứ có vẻ ổn.

Bạn có bất kỳ ý tưởng nào về điều này không? Cảm ơn nhiều!

Clément

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

object ScalaFuture { 

    def main(args: Array[String]) { 

    val f: Future[String] = Future { 
     Thread.sleep(2000) 
     "future value" 
    } 

    f.onSuccess { 
     case s => { 
     Console.println("Console.println OK!") 
     System.out.println("System.out.println OK!") 
     } 
    } 

    Await.ready(f, 60 seconds) 
    } 

} 
+0

Làm việc tốt cho tôi. Điều gì sẽ xảy ra nếu bạn ngủ trong vài giây sau khi 'Await.ready'? –

+0

Nếu tôi ngủ vài giây sau khi "Đang chờ", nó hoạt động tốt => Tôi có đầu ra. – ctamisier

+0

Sau đó, nó phải được thoát trước khi 'onSuccess' có thể kích hoạt. –

Trả lời

21

chờ đợi của bạn đang chờ đợi tương lai để hoàn thành, mà được thực hiện sau 2 giây, nhưng nó không chờ onSuccess xử lý, mà thực hiện trong một thread (tương tự như trong tương lai), nhưng sau Await.ready(f, 60 seconds), do đó, quá trình thoát sớm hơn bạn in một cái gì đó. Để xử lý nó một cách chính xác - tạo ra tương lai mới cho onComplete:

val f: Future[String] = Future { 
    Thread.sleep(2000) 
    "future value" 
} 

val f2 = f map { s => 
    println("OK!") 
    println("OK!")  
} 

Await.ready(f2, 60 seconds) 
println("exit") 

Kết quả cho Await.ready(f, ...):

exit 
OK! 
OK! 

Kết quả cho Await.ready(f2, ...):

OK! 
OK! 
exit 
+0

Ok tuyệt vời tôi đã hiểu. Vì vậy, nếu tôi không sai: đây là một cách giải quyết khi chúng ta sử dụng một hàm main(). Bạn có nghĩ rằng ExecutionContext có liên quan đến điều này và một "đặc biệt" có thể ngăn chặn điều này không? Tôi đã có một cái nhìn về tương lai được thực hiện bởi twitter và có vẻ như "Scheduler" của họ xử lý này (tôi không cần await.ready hoặc bọc tương lai với cùng một trường hợp sử dụng), nhưng đây là một câu chuyện khác. Cảm ơn bạn đã giúp đỡ ! – ctamisier

+0

Nó không phải là cách giải quyết. Đó là một cách chính xác để làm những việc như vậy (nếu bạn chỉ có một luồng với Await trong ứng dụng của mình) - đặc biệt là cho kiểu hàm - vì bạn chỉ có một kết quả trong ứng dụng của mình - bạn nên trả lại nó (và đợi nó) 'IO' nếu ứng dụng của bạn dựa trên REPL (trong các trường hợp khác - người dùng nên tắt nó theo cách thủ công từ giao diện người dùng, do đó không cần chờ đợi). Một tùy chọn khác - là sử dụng ExecutionContext (và bên dưới ThreadPool), tạo ra các luồng có cờ 'isDaemon' sai - xem http://stackoverflow.com/questions/16612517/execution-context-without-daemon-threads-for-futures. – dk14

+0

Tại sao 'Await.ready (f, ...): 'in ra' OK! '? Không có 'println (" OK! ")' Trong 'f'. Tôi không biết làm thế nào để hòa giải 'f' với một đầu ra như mong đợi. –

-8

Chỉ cần đặt readLine() trong mã của bạn.

Các vấn đề liên quan