多线程上传和管理

最近因为项目需要,要大规模的上传照片和mp4。一开始的时候,我是直接使用new Thread创建新线程上传,但是因为上传的量实在太大,而且有时候没有网络,这个就会导致线程的极大量的创建。最后导致内存泄漏。于是 ,只能换另外一种方法了---线程池。

 

项目需求是,要将大文件分解成小文件,然后进行分片上传。这个demo里面只是做了文件切割,分片上传和单个上传。而整个大文件切割的时候,会生成多个分片。这个时候需要多线程进行上传,上传完了之后需要发送合并指令。这就会用到线程里面的

countDownLatch.await();

方法。他会等到多个线程执行完全部任务之后才执行下一行代码。这样完美的解决了之前担心的问题(就是不知道什么时候线程已经全部运行完本次任务的问题)。好了,废话少说。源码撸上

package android.rockchip.update.threadpooltask.upload;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ThreadPoollExcutorUtil {

    //线程进度回调
    private final static int THREAD_PROGRESS_CODE=100;
    //线程完成
    private final static int THREAD_FINISH_CODE=101;
    //线程被中断
    private final static int THREAD_INTERRUPT_CODE=102;
    //所有线程完成
    private final static int THREAD_ALL_SUCCESS_CODE=103;
    //所有线程执行失败
    private final static int THREAD_ALL_FAILED_CODE=104;
    //handler传递进度值
    private final static String THREAD_FILEPATH="THREAD_FILEPATH";
    //handler传递position值
    private final static String THREAD_POSITION="THREAD_POSITION";
    //线程池核心数
    private int threadCore=3;
    //线程池
    private ExecutorService executor;
    //成功的数量
    int successCount=0;
    //失败的数量
    int failedCount=0;

    private OnUploadListener onUploadListener;
    private UploadHandler handler;

    public ThreadPoollExcutorUtil(){
        init();
    }

    public ThreadPoollExcutorUtil(int threadCore){
        this.threadCore=threadCore;
        init();
    }

    public void setOnUploadListener(OnUploadListener uploadListener){
        this.onUploadListener=uploadListener;
    }

    private void init() {
        handler=new ThreadPoollExcutorUtil.UploadHandler(this);
        successCount=0;
        failedCount=0;
        executor= Executors.newFixedThreadPool(threadCore);
    }

    public void shutDownNow(){
        //终端所有线程
        executor.shutdownNow();
    }

    public void submitAll(final ArrayList<UploadItem> uploadItemArrayList){

        //在这里设置每次的任务值,countDownLatch.await();会一直等待,等到线程处理完全部任务之后,
        // 再跑到下一句代码
        CountDownLatch countDownLatch=new CountDownLatch(uploadItemArrayList.size());
        int i=0;
        //历遍文件
        for(UploadItem uploadItem:uploadItemArrayList){
            final Bundle bundle=new Bundle();
            bundle.putString(THREAD_FILEPATH,uploadItem.getFilePath());
            i++;
            executor.submit(new UpLoadFile(countDownLatch, i, uploadItem, new OnThreadResultListener() {
                @Override
                public void onProgressChange(int persent) {

                }

                @Override
                public void onFinish() {
                    Message.obtain(handler,THREAD_FINISH_CODE,bundle).sendToTarget();
                    successCount++;
                    if (successCount==uploadItemArrayList.size()){
                        successCount=0;
                        failedCount=0;
//                        handler.sendEmptyMessage(THREAD_ALL_SUCCESS_CODE);
                    }else if (failedCount!=0 && (failedCount+successCount==uploadItemArrayList.size())){
                        successCount=0;
                        failedCount=0;
//                        handler.sendEmptyMessage(THREAD_ALL_FAILED_CODE);
                    }
                }

                @Override
                public void onInterrupted() {
                    failedCount++;
                    if (successCount+failedCount==uploadItemArrayList.size()){
                        successCount=0;
                        failedCount=0;
//                        handler.sendEmptyMessage(THREAD_ALL_FAILED_CODE);
                    }
                }
            }));
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //全部任务跑完,开始下一个
        handler.sendEmptyMessage(THREAD_ALL_SUCCESS_CODE);
    }

    private static class UploadHandler extends Handler {

        private WeakReference<ThreadPoollExcutorUtil> weakReference;
        private UploadHandler(ThreadPoollExcutorUtil object){
            super(Looper.getMainLooper());//执行在UI线程
            weakReference=new WeakReference<>(object);
        }

        @Override
        public void handleMessage(Message msg) {
            ThreadPoollExcutorUtil threadPoollExcutorUtil=weakReference.get();
            if (threadPoollExcutorUtil!=null){
                Bundle data= (Bundle) msg.obj;
                String filePath;
                switch (msg.what){
                    case THREAD_PROGRESS_CODE:{
//                        filePath=data.getString(THREAD_FILEPATH);
                        break;
                    }
                    case THREAD_FINISH_CODE:{
                        filePath=data.getString(THREAD_FILEPATH);
                        threadPoollExcutorUtil.onUploadListener.onThreadFinish(filePath);
                        break;
                    }
                    case THREAD_INTERRUPT_CODE:{
                        filePath=data.getString(THREAD_FILEPATH);
//                        threadPoollExcutorUtil.onUploadListener.onAllFailed();
                        break;
                    }
                    case THREAD_ALL_SUCCESS_CODE:{
                        threadPoollExcutorUtil.onUploadListener.onAllSuccess();
                        break;
                    }
                    case THREAD_ALL_FAILED_CODE:{
                        threadPoollExcutorUtil.onUploadListener.onAllFailed();
                        break;
                    }
                }
            }

            super.handleMessage(msg);
        }
    }
}

demo的下载地址:https://download.csdn.net/download/xiaoyifeishuang1/12103605

 

发布了37 篇原创文章 · 获赞 2 · 访问量 9494
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览