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