首页 > 代码库 > 多线程获取yahoo股票信息

多线程获取yahoo股票信息

首先给到需要获取和计算的股票,存入一个文本中,如stocks.txt
01AAPL,2505
02AMGN,3406
03AMZN,9354
04BAC,9839
05BMY,5099
06CAT,8463
07C,1500
08CMCSA,6144
09CSCO,4589
10CVX,9696
11DIS,4804
12DOW,3654
13EMC,4835
14FDX,4753
15GD,3919
16GE,7003
17GOOG,6631
18HAL,2593
19HPQ,6157
20IBM,1728
21INTC,4053
22JPM,1665
23LMT,4402
24MET,3712
25MO,3764
26MSFT,2813
27NKE,6447
28NSC,5537
29ORCL,7136
30PFE,659
31RTN,5063
32S,8219
33SO,7175
34TXN,1410
35USB,3099
36VZ,9826
37WMT,6478

       


            然后定义个抽象类,用于读取这个stocks.txt中存放的股票信息,并计算出股票的总值和读取花费的时间。代码如下:

01public 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}

        

        然后,我们用传统的单线程方式,依次去读取并计算股票,并打印总价和花费的时间,代码如下:

01public 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}

            由于网络问题,我这里运行之后,得到的结果是:

1Your net asset value is $18,317,338.21
2Time (seconds) taken 18.080151543

            

            紧接着,我们用多线程方式,读取并计算,并打印总价和时间花费

01public 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}

        在跟上面同等的网络环境下,这段代码运行之后的结果为:

1Number of Cores available is 4
2Pool size is 40
3Your net asset value is $18,317,338.21
4Time (seconds) taken 0.715660335