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 | 
原文地址:http://blog.csdn.net/phantomes/article/details/25188043