首先给到需要获取和计算的股票,存入一个文本中,如stocks.txt
01 |
AAPL,2505 |
02 |
AMGN,3406 |
03 |
AMZN,9354 |
04 |
BAC,9839 |
05 |
BMY,5099 |
06 |
CAT,8463 |
07 |
C,1500 |
08 |
CMCSA,6144 |
09 |
CSCO,4589 |
10 |
CVX,9696 |
11 |
DIS,4804 |
12 |
DOW,3654 |
13 |
EMC,4835 |
14 |
FDX,4753 |
15 |
GD,3919 |
16 |
GE,7003 |
17 |
GOOG,6631 |
18 |
HAL,2593 |
19 |
HPQ,6157 |
20 |
IBM,1728 |
21 |
INTC,4053 |
22 |
JPM,1665 |
23 |
LMT,4402 |
24 |
MET,3712 |
25 |
MO,3764 |
26 |
MSFT,2813 |
27 |
NKE,6447 |
28 |
NSC,5537 |
29 |
ORCL,7136 |
30 |
PFE,659 |
31 |
RTN,5063 |
32 |
S,8219 |
33 |
SO,7175 |
34 |
TXN,1410 |
35 |
USB,3099 |
36 |
VZ,9826 |
37 |
WMT,6478 |
然后定义个抽象类,用于读取这个stocks.txt中存放的股票信息,并计算出股票的总值和读取花费的时间。代码如下:
01 |
public abstract class AbstractNAV { |
02 |
public static Map<String, Integer> readTickers() throws IOException { |
03 |
final BufferedReader reader = |
04 |
new BufferedReader( new FileReader( "d:/stocks.txt" )); |
05 |
|
06 |
final Map<String, Integer> stocks = new HashMap<String, Integer>(); |
07 |
|
08 |
String stockInfo = null ; |
09 |
while ((stockInfo = reader.readLine()) != null ) { |
10 |
final String[] stockInfoData = stockInfo.split( "," ); |
11 |
final String stockTicker = stockInfoData[ 0 ]; |
12 |
final Integer quantity = Integer.valueOf(stockInfoData[ 1 ]); |
13 |
|
14 |
stocks.put(stockTicker, quantity); |
15 |
} |
16 |
|
17 |
return stocks; |
18 |
} |
19 |
|
20 |
public void timeAndComputeValue() |
21 |
throws ExecutionException, InterruptedException, IOException { |
22 |
final long start = System.nanoTime(); |
23 |
|
24 |
final Map<String, Integer> stocks = readTickers(); |
25 |
final double nav = computeNetAssetValue(stocks); |
26 |
|
27 |
final long end = System.nanoTime(); |
28 |
29 |
final String value = new DecimalFormat( "$##,##0.00" ).format(nav); |
30 |
System.out.println( "Your net asset value is " + value); |
31 |
System.out.println( "Time (seconds) taken " + (end - start)/ 1 .0e9); |
32 |
} |
33 |
34 |
public abstract double computeNetAssetValue( |
35 |
final Map<String, Integer> stocks) |
36 |
throws ExecutionException, InterruptedException, IOException; |
37 |
} |
然后,我们用传统的单线程方式,依次去读取并计算股票,并打印总价和花费的时间,代码如下:
01 |
public class SequentialNAV extends AbstractNAV { |
02 |
public double computeNetAssetValue( |
03 |
final Map<String, Integer> stocks) throws IOException { |
04 |
double netAssetValue = 0.0 ; |
05 |
for (String ticker : stocks.keySet()) { |
06 |
netAssetValue += stocks.get(ticker) * YahooFinance.getPrice(ticker); |
07 |
} |
08 |
return netAssetValue; |
09 |
} |
10 |
|
11 |
public static void main( final String[] args) |
12 |
throws ExecutionException, IOException, InterruptedException { |
13 |
new SequentialNAV().timeAndComputeValue(); |
14 |
} |
15 |
} |
由于网络问题,我这里运行之后,得到的结果是:
1 |
Your net asset value is $ 18 , 317 , 338.21 |
2 |
Time (seconds) taken 18.080151543 |
紧接着,我们用多线程方式,读取并计算,并打印总价和时间花费
01 |
public class ConcurrentNAV extends AbstractNAV { |
02 |
public double computeNetAssetValue( final Map<String, Integer> stocks) |
03 |
throws InterruptedException, ExecutionException { |
04 |
final int numberOfCores = Runtime.getRuntime().availableProcessors(); |
05 |
final double blockingCoefficient = 0.9 ; |
06 |
final int poolSize = ( int )(numberOfCores / ( 1 - blockingCoefficient)); |
07 |
08 |
System.out.println( "Number of Cores available is " + numberOfCores); |
09 |
System.out.println( "Pool size is " + poolSize); |
10 |
//Callable接口的实例,用于被另一个线程执行call(),并返回,无返回则抛出异常。 |
11 |
//它类似于Runnable接口,而Runnable 不会返回结果,并且无法抛出经过检查的异常。 |
12 |
final List<Callable<Double>> partitions = |
13 |
new ArrayList<Callable<Double>>(); |
14 |
for ( final String ticker : stocks.keySet()) { |
15 |
partitions.add( new Callable<Double>() { |
16 |
public Double call() throws Exception { |
17 |
return stocks.get(ticker) * YahooFinance.getPrice(ticker); |
18 |
} |
19 |
}); |
20 |
} |
21 |
|
22 |
//定义线程池 |
23 |
final ExecutorService executorPool = |
24 |
Executors.newFixedThreadPool(poolSize); |
25 |
//Future接口的实例,通过get()方法,获取多线程下异步的计算结果。 |
26 |
//必要时,计算完成前可阻塞该方法,可通过cancel()取消计算,一旦计算完成,则无法取消。 |
27 |
final List<Future<Double>> valueOfStocks = |
28 |
executorPool.invokeAll(partitions, 10000 , TimeUnit.SECONDS); |
29 |
30 |
double netAssetValue = 0.0 ; |
31 |
for ( final Future<Double> valueOfAStock : valueOfStocks) |
32 |
netAssetValue += valueOfAStock.get(); |
33 |
34 |
executorPool.shutdown(); |
35 |
return netAssetValue; |
36 |
} |
37 |
38 |
public static void main( final String[] args) |
39 |
throws ExecutionException, InterruptedException, IOException { |
40 |
new ConcurrentNAV().timeAndComputeValue(); |
41 |
} |
42 |
} |
在跟上面同等的网络环境下,这段代码运行之后的结果为:
1 |
Number of Cores available is 4 |
2 |
Pool size is 40 |
3 |
Your net asset value is $ 18 , 317 , 338.21 |
4 |
Time (seconds) taken 0.715660335 |
多线程获取yahoo股票信息
时间: 2024-10-25 12:02:32