`
chenzehe
  • 浏览: 532140 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

面试题——在一个文本里有N多个数据,使用多线程最快求和

 
阅读更多

思路:把所有数据分组,每组使用一个线程去计算结果,计算完后再把结果汇总

具体实现如下:

1、用数据模拟文本里的数据

2、声明一个线程池和实现一个可返回结果的Callable接口

3、把果返回结果Future放到CopyOnWriteArrayList中用于结果集计算

4、此算法的缺点有待改进的地方是结果汇总时是被动去检测,而不是某个结果计算完成后主动去汇总,既然是分段计算,如果数据量足够大时,应该采用递归去实现分段汇总会更好

/**
 * Huisou.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */

package thread;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @description
 * 
 * @author chenzehe
 * @email hljuczh@163.com
 * @create 2013-3-8 上午12:20:27
 */

public class CalculateTest {
	public static void main(String[] args) {
		int[] intNums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };
		System.out.println("Calculate start...");
		System.out.println("Calculate result:" + Calculate.calculate(intNums));
		System.out.println("Calculate finished.");
	}
}

class Calculate {
	static int				poolSize	= 5;
	static ExecutorService	executor	= Executors.newFixedThreadPool(2);
	
	/**
	 * 
	 * @param targetNum
	 * @return
	 * @description 使用多线程对targetNum数组求和
	 * @author chenzehe
	 * @todo
	 */
	public static int calculate(int[] targetNum) {
		int result = 0;
		try {
			// 返回结果Future放到CopyOnWriteArrayList中用于结果集计算
			List<Future<Integer>> futures = new CopyOnWriteArrayList<Future<Integer>>();
			for (int i = 0; i < poolSize; i++) {
				// 提交任务
				futures.add(executor.submit(new CalculateCallable(targetNum, poolSize, i)));
			}
			// 等待返回结果
			while (true) {
				if (futures.size() == 0) {
					break;// 全部返回则跳出
				}
				for (Future<Integer> future : futures) {
					System.out.println("waiting...");
					if (future.isDone()) {
						result += future.get();
						futures.remove(future);// 有返回结果就移出
					}
				}
			}
			executor.shutdown();
		}
		
		catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}
}

class CalculateCallable implements Callable<Integer> {
	int[]	targetNum;
	int		threadNum;
	int		poolSize;
	
	public CalculateCallable(int[] targetNum, int poolSize, int threadNum) {
		this.targetNum = targetNum;
		this.poolSize = poolSize;
		this.threadNum = threadNum;
	}
	
	@Override
	public Integer call() {
		// 根据某种算法算出这里需要读取某部分数据,此处只是简单平均
		int result = 0;
		int eachSize = (targetNum.length + poolSize) / poolSize;
		int start = eachSize * threadNum;
		int end = start + eachSize;
		for (int i = start; i < end && i < targetNum.length; i++) {
			result += targetNum[i];
		}
		try {
			// 模拟长时间的运算
			Thread.sleep(3000);
		}
		catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
}

 

 此解决方案缺点现已使用JDK7中Fork-Join模式解决。

 

 

分享到:
评论
1 楼 showtimes52007 2013-03-08  
关于多线程更多的面试题,这篇文章有详细介绍:http://www.sujunqiang.com/archives/227.html

相关推荐

Global site tag (gtag.js) - Google Analytics