- 论坛徽章:
- 19
|
@duanjigang @send_linux
@hbsycw @redcap0 @zavakid @gnah
Java虚拟机编程技术大家谈---多核和并发编程
我在这个活动中获得了《Java虚拟机并发编程 》图书1本.看了一下,照着书上的例子作了一下,发现了一个问题.
在书第18页的那个关于线程池的例子,我在原例子上略作了一些改动,并没有影响到核心问题,但是每次运行的结果都是不确定的
以下是我的测试代码
这个类是从服务器获取数据文件,例子中的网址是雅虎财经的,我现在打开那个连接已经无效了,因此使用本地的Nginx提供文件 - package com.fangzhaoguo.finance;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.MalformedURLException;
- import java.net.URL;
- public class YahooFinance {
- final static int ID = 0;
- final static int Name = 1;
- private URL url;
- private BufferedReader reader;
- public YahooFinance(final String host) {
- try {
- url = new URL(host);
- reader = new BufferedReader(new InputStreamReader(url.openStream()));
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public double getPrice(final String ticker, int way) {
- String data = null;
- String[] dataItem;
- double lastPrice = 0;
- try {
- while (null != (data = reader.readLine())) {
- dataItem = data.split(",");
- if (ticker.equals(dataItem[way])) {
- lastPrice = Double.valueOf(dataItem[dataItem.length - 1]);
- break;
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return lastPrice;
- }
- public void close() {
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
复制代码这个类就是自己建立线程池来处理并发的请求,以前不是并发的时候完全没有问题,改成并发之后,每次运行的结果都不一样 - package com.fangzhaoguo.finance;
- import java.io.BufferedReader;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- import java.util.concurrent.TimeUnit;
- public class YahooFinanceNAV {
- String host, filename;
- YahooFinance finance;
- Map<String, Integer> stocks;
- public YahooFinanceNAV(String host, String filename) {
- this.host = host;
- this.filename = filename;
- finance = new YahooFinance(host);
- stocks = new HashMap<String, Integer>();
- }
- public void readTickers() {
- try {
- final BufferedReader reader = new BufferedReader(new FileReader(
- filename));
- String info = null;
- String[] infoItem;
- while (null != (info = reader.readLine())) {
- infoItem = info.split(",");
- stocks.put(infoItem[0], Integer.valueOf(infoItem[1]));
- }
- reader.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private int getPoolSize() {
- return 4 + stocks.size() / Runtime.getRuntime().availableProcessors();
- }
- public double computeNAV() {
- double NAV = 0.0;
- int poolSize = getPoolSize();
- List<Callable<Double>> partitions = new ArrayList<Callable<Double>>();
- for (final String ticker : stocks.keySet()) {
- partitions.add(new Callable<Double>() {
- public Double call() throws Exception {
- return stocks.get(ticker)
- * finance.getPrice(ticker, YahooFinance.ID);
- }
- });
- }
- ExecutorService executorService = Executors
- .newFixedThreadPool(poolSize);
- try {
- List<Future<Double>> valFutures = executorService.invokeAll(
- partitions, 10000, TimeUnit.SECONDS);
- for (final Future<Double> vaFuture : valFutures) {
- NAV += vaFuture.get();
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- }
- executorService.shutdown();
- finance.close();
- return NAV;
- }
- }
复制代码- package com.fangzhaoguo.finance;
- public class Main {
- public static void main(String[] args) {
- YahooFinanceNAV yahooFinanceNAV = new YahooFinanceNAV(
- "http://localhost/table.csv", "stocks.dat");
- yahooFinanceNAV.readTickers();
- System.out.println(yahooFinanceNAV.computeNAV());
- }
- }
复制代码 |
|