大文件 and 多下载任务的封装(一)---线程池的封装(ThreadPool,TheadManager)
来源:互联网 发布:日系淘宝店铺推荐 编辑:程序博客网 时间:2024/05/01 19:13
ThreadManager
原文地址
大文件 and 多下载任务的封装二
大文件 and 多下载任务的封装三·
前段时间对三级缓存机制做了系统的分析,但是对于网络下载的问题还有很多,比如今天遇到的问题,针对一些需要下载大文件,并且需要进行多线程下载的应用来说,(比如,像一些应用商店,软件的下载和一些累似的多线程的下载类型)就需要用到线程池,下载就简单介绍对线程池的封装
一.为什么要使用线程池
根据android单线程模式规定,android只允许有一个主线程,也就是UI线程,一切更新UI的操作必须在UI线程中使用,然而对应的一切的耗时操作,只允许在子线称中执行,所以针对子线称的下载操作,可以使用线程池进行管理,所以封装线程吃对线程池管理工具,也是非常实用的。
- 提升性能。创建和消耗对象费时,费CPU资源.
- 防止内存过度消耗。控制活动线程的数量,防止并发线程过多。
- 最大的好处就是,当我们想使用时可以直接新建然后加入线程池即可,也可以对线程进行复用,当我们不想使用的时候直接就可以把它关闭。
二.为什么要对线程池进行封装
有的人可能会说, java.util.concurrent.ThreadPoolExecutor;提供了原生的线程池,我们为什么还要对它进行封装呢?直接使用不就好了,那么问题来了?
- .ThreadPoolExecutor的使用必须保证一个app中只能拥有一个(也就是必须保证单例模式),否则也无法保证子线程的数木
- 封装是为了更好的管理线程,是为了优化代码的使用效率,更好的管理代码。
三.线程池进行封装
####(一)原理分析
- 首先先看一下ThreadPoolExecutor的参数
/** 下面对线程池的方法参数进行解释,其余两个就不解说了,一些参数使用系统默认的即可, Runtime.getRuntime().availableProcessors();进行设置 对于休息时间,则是为了考虑系统长时间运行而导致的系统发热现象, 一般情况下可以选择为0L**/ThreadPoolExecutor executor = new ThreadPoolExecutor( //1.第一个参数:核心的线程数, corePoolSize, //2.第二个参数,默认使用的最大线程数 maximumPoolSize, //3.线程执行时的休眠时间的数值, keepAliveTime, //4.线程执行时休眠的时间的单位,也就是上一个参数的单位 TimeUnit.SECONDS, //5.线程的队列 new LinkedBlockingQueue<Runnable>(), //6.生产线程的工厂 Executors.defaultThreadFactory(), //7.线程异常的处理策略 new ThreadPoolExecutor.AbortPolicy() );
- 因为线程池必须保持一个app中只能有一个实例,所以我们使用单例模式,在这里可以使用懒汉模式
//这里使用的是ThreadManager类,把它设置称单例//而ThreadPool则是在内部类中引用 private static ThreadPool Instance; //单例模式,获取线程池的实例 public static ThreadPool getInstance(){ if(Instance == null){ synchronized (ThreadPool.class){ if(Instance == null){ int threadCount = Runtime.getRuntime().availableProcessors(); Instance = new ThreadPool(threadCount,threadCount,1L); } } } return Instance; }
- 对与线程池来说,我们首先应该有一个向线程池中添加线程的操作
public void execute(Runnable r){ //当ThreadPoolExecutor为null时才新建一个,否则使用原有的。 if(executor == null){ executor = new ThreadPoolExecutor( corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); } if(executor != null){//如果不为空,那么就直接执行此子线称 executor.execute(r); } }
- 当我们对已经开始下载的线程突然不想下载了,或者点错了,那么就需要取消线程
//在这里我们只需要把线程从线程池中移除 public void cancel(Runnable r){ if(executor != null){ //虽然已经移除了,但是下载还是正在运行的,所以我们应该在子线称动态添加取消事件,进行取消 executor.getQueue().remove(r); } }
- 为了防止ThreadManager被直接new出对象,所以应该对构造方法进行限制
private Thread<Manager(){}
四.ThreadManager的使用
//这里是简单的使用Runnable r = new Runnable(){}ThreadManager.getInstance().execute(r);
五.代码
package com.example.orchid.googleplatstore.manager;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * Created by orchid * on 16-11-4. * 线程池类的封装 * */public class ThreadManager { private static ThreadPool Instance; //单例模式,获取线程池的实例 public static ThreadPool getInstance(){ if(Instance == null){ synchronized (ThreadPool.class){ if(Instance == null){ int threadCount = Runtime.getRuntime().availableProcessors(); Instance = new ThreadPool(threadCount,threadCount,1L); } } } return Instance; } public static class ThreadPool{ private ThreadPoolExecutor executor; private int corePoolSize; private int maximumPoolSize; private long keepAliveTime; public ThreadPool(int corePoolSize,int maximumPoolSize,long keepAliveTime) { this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.keepAliveTime = keepAliveTime; } public void execute(Runnable r){ if(executor == null){ //线程池执行者。 //参1:核心线程数;参2:最大线程数;参3:线程休眠时间;参4:时间单位;参5:线程队列;参6:生产线程的工厂;参7:线程异常处理策略 executor = new ThreadPoolExecutor( corePoolSize,maximumPoolSize,keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); } if(executor != null){ executor.execute(r); } } //取消线程 public void cancel(Runnable r){ if(executor != null){ executor.getQueue().remove(r); } } }}
1 0
- 大文件 and 多下载任务的封装(一)---线程池的封装(ThreadPool,TheadManager)
- 大文件 and 多下载任务的封装(三)--断点续传,下载类的整合封装,以及使用
- 大文件 and 多下载任务的封装(二)--观察者模式--实现下载进度的实时更新
- 大文件下载(封装)
- 面向对象的线程池Threadpool的封装
- C++封装POSIX 线程库(一)互斥锁的封装
- 基于任务的线程封装
- iOS开发 -文件下载(下载功能的封装)
- linux c++下将pthread封装成threadpool(线程池)
- C++封装POSIX 线程库(三)线程的封装
- 面向对象的三大特性之(一)封装
- NSOperation封装- 多任务下载
- 模块的封装(一):C语言类的封装
- MVC框架的封装(一)入口文件
- ThreadPool(线程池)
- 简单的封装网络下载almofire(一)
- android的线程封装(Thread)
- 异步线程任务封装
- 根据返回的电量,实现充电状态,充电完成电量显示
- Spring 全注解配置 bean 和 调用 (8) @Aspect注解不生效解决办法 和 no-static 的警告解决办法
- Stark_【指针】一点个人的指针学习记录
- 解的个数(扩展欧几里得解不定方程)
- webpack构建vue项目(配置篇)
- 大文件 and 多下载任务的封装(一)---线程池的封装(ThreadPool,TheadManager)
- C++继承
- 二分查找
- c# 多线程 调用带参数函数
- PMP笔记:启动过程组检查事项
- Guided Filter
- curl使用
- 闲来无需要事写了个自增编号的方法
- 分区修剪(Partition Pruning)