面试题——在一个文本里有N多个数据,应用多线程最快求和
面试题——在一个文本里有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; } }
1 楼
showtimes52007
2013-03-08
关于多线程更多的面试题,这篇文章有详细介绍:http://www.sujunqiang.com/archives/227.html