14.7 让净资产应用并发
净资产应用按顺序一次一个查找每支股票的最新价格。主要的延迟就是花费在等待Web应答的时间——网络延迟。重构上面的代码,就可以并发地为所有股票代码获取最新价格了。完成之后,净资产应用的响应应该会更快。
让这个应用并发,可以将调用getLatestClosingPrice()
放到单独的actor里。一旦它们接收到应答,就会发送一个消息给主actor。主actor接收到所有应答之后,计算总净值。这部分是顺序的。下面这段代码达成了这个目标:
UsingScala/FindTotalWorthConcurrent.scala
import scala.actors._
import Actor._
val symbolsAndUnits = StockPriceFinder.getTickersAndUnits
val caller = self
println("Today is " + new java.util.Date())
println("Ticker Units Closing Price($) Total Value($)")
val startTime = System.nanoTime()
symbolsAndUnits.keys.foreach { symbol =>
actor { caller ! (symbol, StockPriceFinder.getLatestClosingPrice(symbol)) }
}
val netWorth = (0.0 /: (1 to symbolsAndUnits.size)) { (worth, index) =>
receiveWithin(10000) {
case (symbol : String, latestClosingPrice: Double) =>
val units = symbolsAndUnits(symbol)
val value = units * latestClosingPrice
println("%-7s %-5d %-16f %f".format(
symbol, units, latestClosingPrice, value))
worth + value
}
}
val endTime = System.nanoTime()
println("The total value of your investments is $" + netWorth)
println("Took %f seconds".format((endTime-startTime)/1000000000.0))
上面代码的输出如下:
Today is Fri Apr 03 11:18:35 MDT 2009
Ticker Units Closing Price($) Total Value($)
ADBE 125 23.280000 2910.000000
XRX 240 4.980000 1195.200000
SYMC 230 16.020000 3684.600000
VRSN 200 20.070000 4014.000000
CSCO 250 18.140000 4535.000000
ALU 150 2.010000 301.500000
NSM 200 11.250000 2250.000000
TXN 190 16.470000 3129.300000
IBM 215 100.820000 21676.300000
INTC 160 15.700000 2512.000000
ORCL 200 18.820000 3764.000000
HPQ 225 33.690000 7580.250000
AAPL 200 112.710000 22542.000000
MSFT 190 19.290000 3665.100000
AMD 150 3.160000 474.000000
The total value of your investments is $84233.25
Took 7.683939 seconds
请你回顾一下上面的代码,确保理解它们的功能。为了让上面的代码起作用,我们运用了本书迄今为止学到的所有概念。
从上面输出里可以看出,净资产值与顺序执行的结果是相同的⑤。不过,并发版本只用了7秒,而顺序版本用了18秒。去吧!在你的机器上试一下这两个版本,观察结果。每天运行它,结果会因股票价格和网络流量而不同。
⑤对不起,Scala代码不会增加我们的净资产,但是它能提升我们的专业水准!