`

并发计算测试

阅读更多

数据:大List<Long>,1000W级别

需求:求和,对每个数据处理后求和

思路:

1.直接循环累加,地球人都知道,呵呵。

2.分割为多个断,启用多个线程并发计算,然后汇总。

 

代码:

 

package org.acooly.note;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.apache.commons.lang.math.RandomUtils;

public class ConcurrentCalculate {

	
	static final int COUNT = 10000000;
	List<Long> data = new ArrayList<Long>(COUNT);
	
	private int threadNum = 5;
	private long total = 0;
	
	public static void main(String[] args) throws Exception{
		ConcurrentCalculate cc = new ConcurrentCalculate();
		cc.generalTestData();
		cc.concurrent();
		cc.direct();
		System.exit(0);
	}
	
	
	/**
	 * 直接计算
	 */
	public void direct(){
		total = 0;
		long start = System.currentTimeMillis();
		for(long l : data){
			add(algorithm_math(l));
		}
		System.out.println("directSum - total:" + total + "; time:" + (System.currentTimeMillis()-start) + "ms");
	}
	
	
	/**
	 * 并发计算
	 * @throws Exception
	 */
	public void concurrent() throws Exception{
		long start = System.currentTimeMillis();
		CountDownLatch countDownLatch = new CountDownLatch(threadNum);
		Executor executor = Executors.newFixedThreadPool(threadNum);
		for (int i = 0; i < threadNum; i++) {
			int subCount = COUNT/5;
			List<Long> subData = new ArrayList<Long>(subCount);
			for (int j = 0; j < subCount; j++) {
				subData.add(data.get(i*subCount+j));
			}
			executor.execute(new CalculateSum(subData,countDownLatch));
		}
		countDownLatch.await();

		//do sum
		System.out.println("concurrentSum(threadNum:"+threadNum+") - total:" + total + "; time:" + (System.currentTimeMillis()-start) + "ms");
		
		countDownLatch = null;
		executor = null;
		//System.exit(0);
	}
	
	/**
	 * 同步汇总线程计算结果
	 * @param subtotal
	 */
	public synchronized void add(long subtotal){
		total += subtotal;
	}
	
	
	/**
	 * 随机数初始化数据
	 */
	public void generalTestData(){
		for (int i = 0; i < COUNT; i++) {
			data.add((long)RandomUtils.nextInt(100));
		}
	}
	
	/**
	 * 算法模拟业务逻辑。默认算法:无计算
	 * @param l
	 * @return
	 */
	public long algorithm_default(long l){
		return l;
	}
	
	/**
	 * 算法模拟业务逻辑。默认算法:简单数学计算。
	 * @param l
	 * @return
	 */
	public long algorithm_math(long l){
		return ((l / 10) + 2 + 1 * l / 100 - 3) % 2;
	}	

	
	
	/**
	 * 计算任务
	 * @author zhangpu
	 *
	 */
	class CalculateSum implements Runnable{

		private List<Long> subData = null;
		private CountDownLatch countDownLatch = null;
		private CalculateSum(List<Long> subData,CountDownLatch countDownLatch) {
			super();
			this.subData = subData;
			this.countDownLatch = countDownLatch;
		}
		
		public void run() {
			int subtotal = 0;
			for (long l : subData) {
				subtotal += algorithm_math(l);
			}
			//System.out.println("subtotal: " + subtotal);
			add(subtotal);
			this.countDownLatch.countDown();
			
		}
		
	}
	
	
}

 

不处理数据,直接求和测试输出(algorithm_default):

 

concurrentSum(threadNum:5) - total:494991761; time:582ms
directSum - total:494991761; time:482ms
 

 

 

数据处理后求和测试输出(algorithm_math):

concurrentSum(threadNum:5) - total:3001475; time:830ms
directSum - total:3001475; time:961ms

 

测试结论:

1.不对数据进行处理,直接求和比并发快。

2.如果对数据进行处理后在求和,随数据处理消耗的增大,并发求和比直接快。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics