14.7 让净资产应用并发

净资产应用按顺序一次一个查找每支股票的最新价格。主要的延迟就是花费在等待Web应答的时间——网络延迟。重构上面的代码,就可以并发地为所有股票代码获取最新价格了。完成之后,净资产应用的响应应该会更快。

让这个应用并发,可以将调用getLatestClosingPrice()放到单独的actor里。一旦它们接收到应答,就会发送一个消息给主actor。主actor接收到所有应答之后,计算总净值。这部分是顺序的。下面这段代码达成了这个目标:

UsingScala/FindTotalWorthConcurrent.scala

  1. import scala.actors._
  2. import Actor._
  3. val symbolsAndUnits = StockPriceFinder.getTickersAndUnits
  4. val caller = self
  5. println("Today is " + new java.util.Date())
  6. println("Ticker Units Closing Price($) Total Value($)")
  7. val startTime = System.nanoTime()
  8. symbolsAndUnits.keys.foreach { symbol =>
  9. actor { caller ! (symbol, StockPriceFinder.getLatestClosingPrice(symbol)) }
  10. }
  11. val netWorth = (0.0 /: (1 to symbolsAndUnits.size)) { (worth, index) =>
  12. receiveWithin(10000) {
  13. case (symbol : String, latestClosingPrice: Double) =>
  14. val units = symbolsAndUnits(symbol)
  15. val value = units * latestClosingPrice
  16. println("%-7s %-5d %-16f %f".format(
  17. symbol, units, latestClosingPrice, value))
  18. worth + value
  19. }
  20. }
  21. val endTime = System.nanoTime()
  22. println("The total value of your investments is $" + netWorth)
  23. println("Took %f seconds".format((endTime-startTime)/1000000000.0))

上面代码的输出如下:

  1. Today is Fri Apr 03 11:18:35 MDT 2009
  2. Ticker Units Closing Price($) Total Value($)
  3. ADBE 125 23.280000 2910.000000
  4. XRX 240 4.980000 1195.200000
  5. SYMC 230 16.020000 3684.600000
  6. VRSN 200 20.070000 4014.000000
  7. CSCO 250 18.140000 4535.000000
  8. ALU 150 2.010000 301.500000
  9. NSM 200 11.250000 2250.000000
  10. TXN 190 16.470000 3129.300000
  11. IBM 215 100.820000 21676.300000
  12. INTC 160 15.700000 2512.000000
  13. ORCL 200 18.820000 3764.000000
  14. HPQ 225 33.690000 7580.250000
  15. AAPL 200 112.710000 22542.000000
  16. MSFT 190 19.290000 3665.100000
  17. AMD 150 3.160000 474.000000
  18. The total value of your investments is $84233.25
  19. Took 7.683939 seconds

请你回顾一下上面的代码,确保理解它们的功能。为了让上面的代码起作用,我们运用了本书迄今为止学到的所有概念。

从上面输出里可以看出,净资产值与顺序执行的结果是相同的⑤。不过,并发版本只用了7秒,而顺序版本用了18秒。去吧!在你的机器上试一下这两个版本,观察结果。每天运行它,结果会因股票价格和网络流量而不同。

⑤对不起,Scala代码不会增加我们的净资产,但是它能提升我们的专业水准!