Wednesday, December 9, 2009

Futures

Futures are mainly tokens returned by an actor that promises a result sometime in the future. The typical place one encounters a future is from an actor. The !! method of an actor returns a future. However in addition the Futures object provides several methods for doing parallel processing without having to write actors (or threads for that matter.)

Note: My use of scala.util.Random requires Scala 2.8 but I think the rest is 2.7.7.
  1. scala> import scala.actors.Futures._                
  2. import scala.actors.Futures._
  3. /* 
  4. The most basic future example.  
  5. Just runs the function in a seperate thread and returns a Future object
  6. for the result
  7. */
  8. scala> future {Thread.sleep(10000);println("hi");10}
  9. res2: scala.actors.Future[Int] = < function0>
  10. /* 
  11. Use one of the future methods for obtaining the actual result
  12. this one blocks tile ready, but other can check if result is ready and so on
  13. */
  14. scala> res2()
  15. hi
  16. res3: Int = 10
  17. /*
  18. This is more interesting. 
  19. The method creates several futures and the using the awaitAll method 
  20. waits for all the futures to complete before continuing
  21. */
  22. scala> def bubbles = {                                                                                                             
  23.      | val bubbles = for( i <- 1 to 20) yield {
  24.      |   future {
  25.      |     Thread.sleep(scala.util.Random.nextInt(20)*500)
  26.      |     println("pop "+i)
  27.      |     "pop "+i
  28.      |   }
  29.      | }
  30.      | awaitAll(30000, bubbles:_*) foreach println _                                                                               
  31.      | }
  32. bubbles: Unit
  33. scala> bubbles
  34. pop 9
  35. pop 12
  36. pop 11
  37. pop 5
  38. pop 3
  39. pop 14
  40. pop 20
  41. pop 10
  42. pop 1
  43. pop 4
  44. pop 16
  45. pop 6
  46. pop 7
  47. pop 2
  48. pop 8
  49. pop 18
  50. pop 15
  51. pop 19
  52. pop 17
  53. pop 13
  54. Some(pop 1)
  55. Some(pop 2)
  56. Some(pop 3)
  57. Some(pop 4)
  58. Some(pop 5)
  59. Some(pop 6)
  60. Some(pop 7)
  61. Some(pop 8)
  62. Some(pop 9)
  63. Some(pop 10)
  64. Some(pop 11)
  65. Some(pop 12)
  66. Some(pop 13)
  67. Some(pop 14)
  68. Some(pop 15)
  69. Some(pop 16)
  70. Some(pop 17)
  71. Some(pop 18)
  72. Some(pop 19)
  73. Some(pop 20)
  74. scala> import java.net._                                                                                        
  75. import java.net._
  76. scala> import scala.io._
  77. import scala.io._
  78. /*
  79. A kind of funny example.  We set off two futures to download the google page
  80. and print the first that finishes
  81. */
  82. scala> def load = {
  83.      | val com = future {
  84.      |   val comStream = new URL("http://www.google.com").openStream()                                                                       
  85.      |   Source.fromInputStream(comStream).getLines().mkString("\n")
  86.      | }
  87.      | val ch = future {
  88.      |   val chStream = new URL("http://www.google.ch").openStream()
  89.      |   Source.fromInputStream(chStream).getLines().mkString("\n")
  90.      | }  
  91.      | awaitEither(ch,com)                                                                                               
  92.      | }
  93. load: Any
  94. scala> load
  95. res0: Any = 
  96. & !doctype html...

No comments:

Post a Comment