自定义ForkJoinPool 执行线程异常场景 源码跟踪

package thread;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

public class ForkJoinPool<T> {

	private final static Logger logger = org.apache.log4j.Logger
			.getLogger(ForkJoinPool.class);

	public static final int AVAILABLE_PROCESSORS_SIZE = Runtime.getRuntime()
			.availableProcessors();

	private ListeningExecutorService executorService = null;

	private ThreadLocal<List<ListenableFuture<T>>> futuresThreadLocal = new ThreadLocal<List<ListenableFuture<T>>>(){
		protected java.util.List<com.google.common.util.concurrent.ListenableFuture<T>> initialValue() {
			 return Lists.newArrayList();
		};
	};

	public ForkJoinPool() {
		this(AVAILABLE_PROCESSORS_SIZE*2);
	}

	public ForkJoinPool(int poolSize) {
		executorService = MoreExecutors
				.listeningDecorator(Executors
						.newFixedThreadPool(poolSize));
	}

	public void createTask() {
	}
	
	
	/**
	 * 
	 * @description
	 * @return ListenableFuture<T>
	 * @Exception
	 */
	public ForkJoinPool<T> addTaskList(final List<Callable<T>> callables) {
		if(callables!=null){
			for(Callable<T> c:callables){
				addTask(c);
			}
		}
		return this;
	}

	/**
	 * 
	 * @description
	 * @return ListenableFuture<T>
	 * @Exception
	 */
	public ForkJoinPool<T> addTask(final Callable<T> callable) {
		ListenableFuture<T> listenableFuture = executorService.submit(callable);
		futuresThreadLocal.get().add(listenableFuture);
		return this;
	}

	/**
	 * 多线程执行商品生成信息
	 * 
	 * @description
	 * @return
	 * @Exception
	 */
	public List<T> executeTask(List<ListenableFuture<T>> futures) {
		long gstartTime = System.currentTimeMillis();
		ListenableFuture<List<T>> successfulQueries = Futures
				.successfulAsList(futures);
		try {
			// 获取所有线程的执行结果
			List<T> lists = successfulQueries.get();
			return lists;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} 
		logger.info(" executeTask ! cost time:"
				+ (System.currentTimeMillis() - gstartTime));

		return null;
	}
	
	/**
	 * 多线程执行商品生成信息
	 * 
	 * @description
	 * @return
	 * @Exception
	 */
	public List<T> executeTask() {
		List<ListenableFuture<T>> futures = futuresThreadLocal.get();
		try {
			return executeTask(futures);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			futuresThreadLocal.remove();
		}
		return null;
	}
	
	
	
	/**
	 * 拆分任务
	 * 
	 * @param tasks
	 * @param 拆分数量
	 * @return
	 */
	public static <T> List<T> mergeTask(List<List<T>> tasks) {
		if(tasks==null){
			return null;
		}
		List<T> list = Lists.newArrayList();
		for(List<T> l:tasks){
			if(l!=null){
				list.addAll(l);
			}
		}
		return list;
	}

	/**
	 * 拆分任务
	 * 
	 * @param tasks
	 * @param 拆分数量
	 * @return
	 */
	public static <T> List<List<T>> splitTask(List<T> tasks, Integer taskSize) {
		List<List<T>> list = Lists.newArrayList();
        if(tasks==null || taskSize <= 0){
			return list;
		} 
        if(tasks.size() < taskSize){
        	list.add(tasks);
        	return list;
        }
         
        
		int baseNum = tasks.size() / taskSize; // 每个list的最小size
		int remNum = tasks.size() % taskSize; // 得到余数

		int index = 0;
		for (int i = 0; i < taskSize; i++) {
			int arrNum = baseNum; // 每个list对应的size
			if (i < remNum) {
				arrNum += 1;
			}
			List<T> ls = Lists.newArrayList();
			for (int j = index; j < arrNum + index; j++) {
				ls.add(tasks.get(j));
			}
			list.add(ls);
			index += arrNum;
		}
		return list;
	}


	public void shutdown() {
		this.executorService.shutdown();
	}

	
	public static void main(String[] args) {
		//测试线程池内异常情况
		ForkJoinPool<Object> forkJoinPool = new ForkJoinPool<>(2);
		forkJoinPool.addTask(new Callable<Object>() {
			@Override
			public Object call() throws Exception {
				throw new RuntimeException("test");
			}
		});
		
		forkJoinPool.addTask(new Callable<Object>() {
			@Override
			public Object call() throws Exception {
				return "123";
			}
		});
		List<Object> list = forkJoinPool.executeTask();
		//[null, 123]
		System.out.println(list);
	}
	
}	
	

引用包:

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
 


关键代码:

ListenableFuture<List<T>> successfulQueries = Futures
                .successfulAsList(futures);

源码跟踪:

com.google.common.util.concurrent.CollectionFuture.ListFuture<V, C>


  /** Used for {@link Futures#allAsList} and {@link Futures#successfulAsList}. */
  static final class ListFuture<V> extends CollectionFuture<V, List<V>> {
    ListFuture(
        ImmutableCollection<? extends ListenableFuture<? extends V>> futures,
        boolean allMustSucceed) {
      init(new ListFutureRunningState(futures, allMustSucceed));
    }

    private final class ListFutureRunningState extends CollectionFutureRunningState {
      ListFutureRunningState(
          ImmutableCollection<? extends ListenableFuture<? extends V>> futures,
          boolean allMustSucceed) {
        super(futures, allMustSucceed);
      }

      @Override
      public List<V> combine(List<Optional<V>> values) {
        List<V> result = newArrayListWithCapacity(values.size());
        for (Optional<V> element : values) {
          result.add(element != null ? element.orNull() : null);
        }
        return unmodifiableList(result);
      }
    }
  }
  
  
com.google.common.util.concurrent.AggregateFuture.RunningState.handleOneInputDone(int, Future<? extends InputT>)
 /**
     * Handles the input at the given index completing.
     */
    private void handleOneInputDone(int index, Future<? extends InputT> future) {
      // The only cases in which this Future should already be done are (a) if it was cancelled or
      // (b) if an input failed and we propagated that immediately because of allMustSucceed.
      checkState(
          allMustSucceed || !isDone() || isCancelled(),
          "Future was done before all dependencies completed");

      try {
        checkState(future.isDone(), "Tried to set value from future which is not done");
        if (allMustSucceed) {
          if (future.isCancelled()) {
            // clear running state prior to cancelling children, this sets our own state but lets
            // the input futures keep running as some of them may be used elsewhere.
            runningState = null;
            cancel(false);
          } else {
            // We always get the result so that we can have fail-fast, even if we don't collect
            InputT result = getDone(future);
            if (collectsValues) {
              collectOneValue(allMustSucceed, index, result);
            }
          }
        } else if (collectsValues && !future.isCancelled()) {
		  //聚合future结果
          collectOneValue(allMustSucceed, index, getDone(future));
        }
      } catch (ExecutionException e) {
        handleException(e.getCause());
      } catch (Throwable t) {
        handleException(t);
      }
    }  
	
com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Future<V>)
  @CanIgnoreReturnValue
  public static <V> V getUninterruptibly(Future<V> future) throws ExecutionException {
    boolean interrupted = false;
    try {
      while (true) {
        try {
          return future.get();
        } catch (InterruptedException e) {
          interrupted = true;
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }

com.google.common.util.concurrent.AbstractFuture.get()
@CanIgnoreReturnValue
  @Override
  public V get() throws InterruptedException, ExecutionException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    Object localValue = value;
    if (localValue != null & !(localValue instanceof SetFuture)) {
      return getDoneValue(localValue);
    }
    Waiter oldHead = waiters;
    if (oldHead != Waiter.TOMBSTONE) {
      Waiter node = new Waiter();
      do {
        node.setNext(oldHead);
        if (ATOMIC_HELPER.casWaiters(this, oldHead, node)) {
          // we are on the stack, now wait for completion.
          while (true) {
            LockSupport.park(this);
            // Check interruption first, if we woke up due to interruption we need to honor that.
            if (Thread.interrupted()) {
              removeWaiter(node);
              throw new InterruptedException();
            }
            // Otherwise re-read and check doneness. If we loop then it must have been a spurious
            // wakeup
            localValue = value;
            if (localValue != null & !(localValue instanceof SetFuture)) {
              return getDoneValue(localValue);
            }
          }
        }
        oldHead = waiters; // re-read and loop.
      } while (oldHead != Waiter.TOMBSTONE);
    }
    // re-read value, if we get here then we must have observed a TOMBSTONE while trying to add a
    // waiter.
    return getDoneValue(value);
  }


com.google.common.util.concurrent.AbstractFuture.getDoneValue(Object)
 /**
   * Unboxes {@code obj}. Assumes that obj is not {@code null} or a {@link SetFuture}.
   */
  private V getDoneValue(Object obj) throws ExecutionException {
    // While this seems like it might be too branch-y, simple benchmarking proves it to be
    // unmeasurable (comparing done AbstractFutures with immediateFuture)
    if (obj instanceof Cancellation) {
      throw cancellationExceptionWithCause("Task was cancelled.", ((Cancellation) obj).cause);
    } else if (obj instanceof Failure) {
      throw new ExecutionException(((Failure) obj).exception);
    } else if (obj == NULL) {
      return null;
    } else {
      @SuppressWarnings("unchecked") // this is the only other option
      V asV = (V) obj;
      return asV;
    }
  }

com.google.common.util.concurrent.CollectionFuture.CollectionFutureRunningState.collectOneValue(boolean, int, V)
@Override
    final void collectOneValue(boolean allMustSucceed, int index, @Nullable V returnValue) {
      List<Optional<V>> localValues = values;

      if (localValues != null) {
        localValues.set(index, Optional.fromNullable(returnValue));
      } else {
        // Some other future failed or has been cancelled, causing this one to also be cancelled or
        // have an exception set. This should only happen if allMustSucceed is true or if the output
        // itself has been cancelled.
        checkState(
            allMustSucceed || isCancelled(), "Future was done before all dependencies completed");
      }
    }

abstract class CollectionFutureRunningState extends RunningState {
    private List<Optional<V>> values;

    CollectionFutureRunningState(
        ImmutableCollection<? extends ListenableFuture<? extends V>> futures,
        boolean allMustSucceed) {
      super(futures, allMustSucceed, true);

      this.values =
          futures.isEmpty()
              ? ImmutableList.<Optional<V>>of()
              : Lists.<Optional<V>>newArrayListWithCapacity(futures.size());

      // Populate the results list with null initially.
      for (int i = 0; i < futures.size(); ++i) {
        values.add(null);
      }
    }

总结:
guava 线程池,线程执行异常情况下返回null,不会抛出异常
	
	

 

转载于:https://my.oschina.net/xiaominmin/blog/1615926

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值