简单的包装一个线程池,存储所有任务的运行结果。

线程池,想必无论是做Android开发的还是做Java开发的对它都不陌生。它可以为我们提高线程的复用,默认情况下核心线程不会被销毁,避免了我们创建和销毁线程带来的开销。也可以为线程设置超时时间,超时才会被销毁。
那我们如何去知道线程池中的任务执行完毕了呢?并且获取任务的执行结果呢?

下面自己写一个类包装我们线程池,实现我们的需求。

下面动手实现以下我们的代码:

首先我们创建一个类MyCompleteExecutorService,在它内部我们定义几个成员变量:

    //持有的线程池实例
    private ExecutorService executorService;
    //用来记录任务执行完成的数量
    private AtomicInteger alreadyFinishNum;
    //存储我们的任务结果
    private ArrayMap<K, V> arrayMap;
    //记录任务的总数
    private int taskNum;

定义我们的构造方法:

    public MyCompleteExecutorService(ExecutorService executorService) {
        this.mExecutorService = executorService;
        //初始化计数器
        this.mAlreadyFinishNum = new AtomicInteger(0);
    }

接下来我们在内部定义两个提交任务的方法,方法内部我们调用线程池提交任务的方法:

    /**
     * 提交Callable任务
     * @param tag
     * @param task
     */
    public void submitTask(K tag ,MyCallable<K,V> task) {
        task.setKey(tag);
        taskNum++;
        mExecutorService.submit(task);
    }

    /**
     * 提交Runnable任务
     * @param runnable
     */
    public void submitTask(MyRunnable runnable) {
        taskNum++;
        mExecutorService.submit(runnable);
    }

定义我们自己的任务类分别继承自Callable和Runnable,
在两个类中,分别持有外部类的弱引用。当任务执行完成我们把已完成的任务计数器+1,如果有返回结果,我们就把返回结果放入我们的mResultMap中。

    /**
     * 继承Callable
     */
    public static abstract class MyCallable<K,V> implements Callable<V> {

        //持有外部类的弱引用
        private WeakReference<MyCompleteExecutorService> mWeakService;
        //任务标识
        private K key;

        public K getKey() {
            return key;
        }

        public void setKey(K key) {
            this.key = key;
        }

        public MyCallable(MyCompleteExecutorService myCompleteExecutor) {
            mWeakService = new WeakReference<>(myCompleteExecutor);
        }

        @Override
        public V call() throws Exception {
            if(mWeakService.get().mResultMap==null){
                mWeakService.get().mResultMap = new ArrayMap();
            }
            //获取我们的返回结果
            V result = doMyCall();
            //任务执行结果放入Map中存储起来
            mWeakService.get().mResultMap.put(key,result);
            //计数器+1
            mWeakService.get().addFinishNum();
            return result;
        }

        /**
         *  子类必须实现这个方法
         * @return
         */
        protected abstract V doMyCall();

    }

    /**
     * 继承Runnable
     */
    public static abstract class MyRunnable implements Runnable {

        private WeakReference<MyCompleteExecutorService> mWeakService;

        public MyRunnable(MyCompleteExecutorService myCompleteExecutor) {
            mWeakService = new WeakReference<>(myCompleteExecutor);
        }

        @Override
        public void run() {
            doMyRunnable();
            if (mWeakService.get() != null) {
                //计数器+1
                mWeakService.get().addFinishNum();
            }
        }

        /**
         * 子类必须实现的方法
         */
        protected abstract void doMyRunnable();
    }


我们的计数器+1的方法:

    private void addFinishNum() {
        mAlreadyFinishNum.incrementAndGet();
        if (mAlreadyFinishNum.get() == taskNum) {
            //全部完成
            if (taskCallback != null) {
               //执行接口方法
                taskCallback.alreadyFinishAllTask(taskNum);
            }
        }
    }

定义我们的回调接口:

    public interface FinishTaskCallback {
        void alreadyFinishAllTask(int finishNum);
    }

    private FinishTaskCallback taskCallback;


    public FinishTaskCallback getTaskCallback() {
        return taskCallback;
    }

    public void setTaskCallback(FinishTaskCallback taskCallback) {
        this.taskCallback = taskCallback;
    }

完整代码实现如下:

public class MyCompleteExecutorService<K, V> {

    //持有的线程池实例
    private ExecutorService mExecutorService;
    //用来记录任务执行完成的数量
    private AtomicInteger mAlreadyFinishNum;
    //存储我们的任务结果
    private ArrayMap<K, V> mResultMap;
    //记录任务的总数
    private int taskNum;

    public ArrayMap<K, V> getArrayMap() {
        return mResultMap;
    }

    public MyCompleteExecutorService(ExecutorService executorService) {
        this.mExecutorService = executorService;
        this.mAlreadyFinishNum = new AtomicInteger(0);
    }


    /**
     * 提交Callable任务
     * @param tag
     * @param task
     */
    public void submitTask(K tag ,MyCallable<K,V> task) {
        task.setKey(tag);
        taskNum++;
        mExecutorService.submit(task);
    }

    /**
     * 提交Runnable任务
     * @param runnable
     */
    public void submitTask(MyRunnable runnable) {
        taskNum++;
        mExecutorService.submit(runnable);
    }

    /**
     * 继承Callable
     */
    public static abstract class MyCallable<K,V> implements Callable<V> {

        //持有外部类的弱引用
        private WeakReference<MyCompleteExecutorService> mWeakService;
        //任务标识
        private K key;

        public K getKey() {
            return key;
        }

        public void setKey(K key) {
            this.key = key;
        }

        public MyCallable(MyCompleteExecutorService myCompleteExecutor) {
            mWeakService = new WeakReference<>(myCompleteExecutor);
        }

        @Override
        public V call() throws Exception {
            if(mWeakService.get().mResultMap==null){
                mWeakService.get().mResultMap = new ArrayMap();
            }
            //获取我们的返回结果
            V result = doMyCall();
            //任务执行结果放入Map中存储起来
            mWeakService.get().mResultMap.put(key,result);
            //计数器+1
            mWeakService.get().addFinishNum();
            return result;
        }

        /**
         *  子类必须实现这个方法
         * @return
         */
        protected abstract V doMyCall();

    }

    /**
     * 继承Runnable
     */
    public static abstract class MyRunnable implements Runnable {

        private WeakReference<MyCompleteExecutorService> mWeakService;

        public MyRunnable(MyCompleteExecutorService myCompleteExecutor) {
            mWeakService = new WeakReference<>(myCompleteExecutor);
        }

        @Override
        public void run() {
            doMyRunnable();
            if (mWeakService.get() != null) {
                //计数器+1
                mWeakService.get().addFinishNum();
            }
        }

        /**
         * 子类必须实现的方法
         */
        protected abstract void doMyRunnable();
    }

    /**
     * 计数器+1的操作
     */
    private void addFinishNum() {
        mAlreadyFinishNum.incrementAndGet();
        Log.v("alreadyFinishNum", mAlreadyFinishNum.get() + "");
        if (mAlreadyFinishNum.get() == taskNum) {
            //全部完成
            if (taskCallback != null) {
                taskCallback.alreadyFinishAllTask(taskNum);
            }
        }
    }

    public interface FinishTaskCallback {
        void alreadyFinishAllTask(int taskNum);
    }

    private FinishTaskCallback taskCallback;


    public FinishTaskCallback getTaskCallback() {
        return taskCallback;
    }

    public void setTaskCallback(FinishTaskCallback taskCallback) {
        this.taskCallback = taskCallback;
    }

}

下面我们测试一下我们写的类:

在这里插入图片描述
通过for循环提交十个任务:

        myCompleteExecutor = new MyCompleteExecutorService<>(Executors.newFixedThreadPool(10));
        //让当前类实现我们的接口
        myCompleteExecutor.setTaskCallback(this);
        for (int i = 0; i < 10; i++) {
            final int finalI1 = i;
            myCompleteExecutor.submitTask(i,new MyCompleteExecutorService.MyCallable<Integer, String>( myCompleteExecutor) {
                @Override
                protected String doMyCall() {
                    int k = 0;
                    while (k <10000000) {
                        k++;
                    }
                    //返回任务结果
                    return String.valueOf(k + finalI1);
                }
            });
        }

实现回调方法,在我们方法中打印结果:

    @Override
    public void alreadyFinishAllTask(int finishTaskNum) {
        if(finishTaskNum!=10){
            return;
        }
        for (int i = 0; i < 10; i++) {
            //打印所有任务的执行结果
            //注意了这里的方法运行在我们的线程池的线程中,如有需要自行切换
            System.out.println("第"+i+"个任务的执行结果是:"+myCompleteExecutor.getArrayMap().get(i));
        }
    }

打印输入如下:
在这里插入图片描述

其实java也为我们内置了一个ExecutorCompletionService类,它里面通过一个阻塞队列存储了所有任务的Future对象,我们可以通过这个Future获取相应任务的执行结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值