package com.uas.account.core;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 任务聚合<br>
 * 将多个分支任务并行处理，将任务处理的结果合并返回
 * 
 * @author yingp
 *
 * @param <V>
 *            返回结果类型
 * @param <T>
 *            传递参数类型
 */
public class MergeTask<V, T> {

	// 缓冲的线程池
	private final ExecutorService threadPool;

	private final CompletionService<V> service;

	// 定义一个带参有返回的callable
	private final ICallable<V, T> callable;

	private int taskCount = 0;

	public MergeTask(ICallable<V, T> callable) {
		this.threadPool = Executors.newCachedThreadPool();
		this.service = new ExecutorCompletionService<V>(threadPool);
		this.callable = callable;
	}

	/**
	 * 添加分支任务
	 * 
	 * @param param
	 *            针对ICallable传递的参数
	 * @return
	 */
	public MergeTask<V, T> join(T param) {
		service.submit(new ICallableAdapter<V, T>(callable, param));
		taskCount++;
		return this;
	}

	/**
	 * 获取聚合的结果，结果扔到List里面返回
	 * 
	 * @return
	 */
	public List<V> execute() {
		threadPool.shutdown();
		int finish = 0;
		List<V> datas = new ArrayList<V>();
		while (finish < taskCount) {
			// 非阻塞方式
			Future<V> future = service.poll();
			if (future != null) {
				try {
					V result = future.get();
					if (result != null) {
						datas.add(result);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				finish++;
			}
			if (finish < taskCount)
				try {
					// 等待50毫秒再进入下一次查找
					TimeUnit.MILLISECONDS.sleep(50);
				} catch (InterruptedException e) {
				}
		}
		return datas;
	}

}
