多线程上传和管理

最近因为项目需要,要大规模的上传照片和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

 

多线程上传文件是一种在计算机网络中常见的文件传输方式。多线程指的是在上传文件的过程中同时启动多个线程来进行文件传输操作,以达到提高上传速度和效率的目的。 在多线程上传文件的过程中,首先需要将要上传的文件划分成多个小块,每个小块由一个线程来处理。每个线程负责上传一个小块的数据,并向目标服务器发送上传请求。同时,为了保证传输的完整性,还需要对每个小块进行校验,确保上传的数据没有出错。 多线程上传文件的主要优点是能够有效提高上传速度。通过同时启动多个线程进行文件传输,可以将文件划分成多个小块并并行上传,从而减少传输的时间。此外,多线程上传还能够利用带宽资源,充分发挥网络的传输能力,提高上传效率。 然而,多线程上传文件也存在一些问题。首先,多线程并发上传需要一定的系统资源,如果线程数量过多可能会导致系统负载过高。其次,多线程上传需要确保各个线程之间的数据同步和完整性,这需要进行一些额外的管理和控制,增加了编程的复杂度。最后,多线程上传可能会造成网络拥塞,当多个用户同时进行大文件上传时,网络带宽资源可能会被占用,导致其他网络请求的延迟。 总之,多线程上传文件能够提高文件传输速度和效率,但也需要考虑到系统资源和网络拥塞等问题。在实际应用中,需要根据具体的上传需求和网络环境来选择是否采用多线程上传方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tiwolf_li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值