一个异步并发模型的实现

在工作中我们经常会碰到并发处理的情况,如我们需要并发上传5张图片到文件服务器等待全部上传完毕后拿到返回链接再提交给逻辑服务器,这个时候5张图片的并发上传模型可以采用Callable+Future+CountDownLatch来处理,下面代码仅供参考学习。



/**
 * @Description:等待全部子任务完成之后才返回的
 */


public abstract class BatchTask<T>  {


    public static final String TAG = "BaseFatherTask";


    public static final SparseArray<BatchTask<?>> tasks = new SparseArray<BatchTask<?>>();
    public static final AtomicInteger sequence = new AtomicInteger(); 
    
    public final int taskId = sequence.getAndIncrement();
    
    private ExecutorService subTaskExecutor;
    private CountDownLatch countDown;
    private ArrayList<Future<T>> subTaskResult = new ArrayList<Future<T>>();
    private List<T> results = new ArrayList<T>();
    private List<BaseChildTask<T>> childTaskList= new ArrayList<BaseChildTask<T>>();
    
    private volatile boolean cancel = false;
    
    public BatchTask(ExecutorService service) {
        this.subTaskExecutor = service;
    }


    protected void cancel() {
    if (childTaskList == null){
    return;
    }
    cancel = true;
    for( int i=0;i<childTaskList.size();i++) {
    childTaskList.get(i).cancel();
    }
    }
    /**
     * 提交所有子任务
     *
     * @return true, 提交成功
     */
    protected boolean submitChildTask(List<NewPostEntityProvider<T>> protocols) {
   
        if (countDown != null ) {
        NLog.e(TAG, "Already running task");
            return false;
        }
        if (protocols == null || protocols.isEmpty()) {
            return true; // 如果子任务列表为空,则返回执行成功
        }
        countDown = new CountDownLatch(protocols.size());
        try {
            for (NewPostEntityProvider<T> childTask : protocols) {
            BaseChildTask<T> task = new BaseChildTask<T>(childTask, countDown);
                Future<T> future = subTaskExecutor.submit(task);
                childTaskList.add(task);
                subTaskResult.add(future);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
   
    /**
     * 等待子任务执行完成
     */
    protected void waitSubTaskDone() {
        if (countDown != null) {
            try {
                countDown.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 关闭线程池
     */
    protected void shutDown() {
    subTaskExecutor.shutdown();
    }
    /**
     * 默认所有子任务执行成功才算成功,否则失败
     *
     * @return
     */
    protected List<T>  checkSubTask() {
    
        for (Future<T> future : subTaskResult) {
            T result = null;
            try {
                result = future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            results.add(result);
        }
       
        return results;
    }


    /**
     * @Description:子任务类,可以完成之后通知外面,只能用于@see BaseFatherTask 中创建
     */


    private class BaseChildTask<T> implements Callable<T> {
        private CountDownLatch countDownLatch;
        private NewPostEntityProvider<T> provider;


        public BaseChildTask(NewPostEntityProvider<T> provider, CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
            this.provider = provider;
        }


        @Override
        public T call() throws Exception {
        if( !cancel) {
        provider.send(true);
        }
            countDownLatch.countDown();
            return provider.getResult();
        }
        
        public void cancel() {
        if( provider != null) {
        provider.cancel();
        }
        countDownLatch.countDown();
        }
    }


   /* public static void cancelTask(int taskId) {
    BatchTask<?> task = tasks.get(taskId);
    if( task != null) {
    task.cancel();
    }
    remove(taskId);
    }
    
    private static void remove(int taskId) {
    tasks.remove(taskId);
    }
    
    public static int runTask(BatchTask<?> task) {
    tasks.append(task.taskId, task);
    new Thread(task).start();
    return task.taskId;
    }
    */
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值