在学习线程池之前需要先了解几个java的线程池
1.newCachedThreadPool
创建一个可缓存线程池,根据长度灵活回收,若无空闲线程,则新建线程
2.newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3.newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
4.newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
他们各自有各自的不足和优点,这里我们且说他们自身的不足吧
第一种,没有最大并发数的控制,所以在没有空线程情况下会无限新建线程,
第二/三种,控制了最大并发数限制,但是没有充分利用空闲线程.
第四种,每次只能执行一个单线程.
相对以上四种来说,我们自己写的线程池管理充分对其缺点进行了弥补.
再来看看异步任务类AsyncTask
原理
5个并发数线程,128个最大可执行线程,空闲时间为1秒
其也存在着很大隐患,比如:
并发数和最大线程池不可控
当线程池超过最大并发数后就会崩溃,因此没有对做"等待"处理
容易造成内存泄漏
更多请参考:http://blog.csdn.net/boyupeng/article/details/49001215
说了这么多别人的不足,是不是觉得自己写的就很厉害了呢,不是,此次篇幅只是简单根据以上各自的进行综合而已,也有很多没有进行详细的处理.
先看看我将要实现的原理
①发布一个任务,任务有三种状态值,待执行,执行中,已完成
初始化为待执行
②根据线程队列(池)中是否存在空闲线程来新建或者复用线程
③超过线程池最大线程数限制,则任务队列处于wait状态
④looper不断检测是否存在wait的任务进行循环执行
首先是任务抽象类
/**
* 主题:任务抽象类
*/
public abstract class ATask {
public static final int TASK_WAITING = 1001;// 待执行
public static final int TASK_EXECUTING = 1002;// 执行中
public static final int TASK_COMPLETE = 1003;// 已完成
private int status = TASK_WAITING;
private String[] params;
// 后台执行
public abstract Object doInBackground(String... params);
// 回调结果
public void doPost(Object object) {
}
/**
* 执行任务
*
* @param params
*/
public void execute(String... params) {
this.params = params;
execute();
}
/**
* 执行任务
*/
public void execute() {
XTaskQueue.getIntance().add(this);
XLooper.getInstance().loop();
}
/**
* 更新任务状态
*
* @param status
*/
public void updateStatus(int status) {
this.status = status;
}
/**
* 获取任务状态
*
* @return
*/
public int getStatus() {
return status;
}
String[] getParams() {
return params;
}
}
其次任务队列
/**
* 主题:任务队列
*/
public class XTaskQueue {
private ArrayList<ATask> taskQueue = new ArrayList();// 任务队列
private ArrayList<ATask> waitingTasks = new ArrayList();// 待执行任务
private static XTaskQueue intance = new XTaskQueue();
private XTaskQueue() {
}
public static XTaskQueue getIntance() {
return intance;
}
/**
* 添加一个任务
*
* @param task
*/
public void add(ATask task) {
taskQueue.add(taskQueue.size(),task);
}
/**
* 获取待执行任务
*
* @return
*/
public ArrayList<ATask> getWaitingTasks() {
waitingTasks.clear();
for (ATask task : taskQueue) {
if (task.getStatus() == ATask.TASK_WAITING) {
waitingTasks.add(task);
}
}
return waitingTasks;
}
public void clear(){
taskQueue.clear();
}
public int size(){
return taskQueue.size();
}
}
线程池
/**
* 主题:线程队列
*/
public class XThreadQueue {
private int limit=3;
private ArrayList<XThread> threadQueue=new ArrayList<>();// 线程队列
private ArrayList<XThread> idleThreads=new ArrayList<>();// 空闲线程
private static XThreadQueue instance=new XThreadQueue();
private XThreadQueue(){}
public static XThreadQueue getInstance(){
return instance;
}
public void add(XThread thread){
threadQueue.add(threadQueue.size(),thread);
}
public void clear(){
threadQueue.clear();
}
/**
* 最线程数
* @param count
*/
public void limit(int count){
this.limit=limit;
}
/**
* 获取最大线程数
* @return
*/
public int getMaxLimitCount() {
return limit;
}
/**
* 获取空闲线程
* @return
*/
public ArrayList<XThread> getIdleThreads(){
idleThreads.clear();
for(XThread thread:threadQueue){
if(thread.getStatus()==XThread.THREAD_IDLE){
idleThreads.add(thread);
}
}
return idleThreads;
}
/**
* 线程池数量
* @return
*/
public int size(){
return threadQueue.size();
}
}
looper
/**
* 主题:looper
*/
public class XLooper {
private boolean loop = false;
private static XLooper instance = new XLooper();
public static XLooper getInstance() {
return instance;
}
private XLooper() {
}
public synchronized void loop() {
loop = true;
ArrayList<ATask> waitingTasks = XTaskQueue.getIntance().getWaitingTasks();// 获取待执行任务
ArrayList<XThread> idleThreads = XThreadQueue.getInstance().getIdleThreads();// 获取空闲线程
if (waitingTasks.size() == 0) return;
Log.d("tag", "当前总任务数:" + XTaskQueue.getIntance().size() + ",当前总线程数:" + XThreadQueue.getInstance().size() + ",当前待执行任务数:" + waitingTasks.size() + ",当前空闲线程数:" + idleThreads.size());
if (idleThreads.size() > 0) {
int count = Math.min(waitingTasks.size(), idleThreads.size());
for (int i = 0; i < count; i++) {
Log.d("tag", "复用线程");
ATask task = waitingTasks.get(i);
XThread thread = idleThreads.get(i);
thread.insert(task, task.getParams());
}
} else {
if (XThreadQueue.getInstance().size() < XThreadQueue.getInstance().getMaxLimitCount()) {// 当前线程池还没有达到限制数量,则还可以新建线程并执行任务
int remainCount = XThreadQueue.getInstance().getMaxLimitCount() - XThreadQueue.getInstance().size();// 剩余可创建线程数
int canCreateCount = Math.min(remainCount, waitingTasks.size());// 取消可创建线程和待执行任务大小的最小值
for (int i = 0; i < canCreateCount; i++) {
Log.d("tag", "新建线程");
ATask task = waitingTasks.get(i);
XThread thread = new XThread();
thread.insert(task, task.getParams());
XThreadQueue.getInstance().add(thread);
thread.start();
}
}
}
}
public void cancel() {
loop = false;
XThreadQueue.getInstance().clear();
XTaskQueue.getIntance().clear();
}
public boolean isLoop(){
return loop;
}
}
工作线程
/**
* 主题:工作线程
*/
public class XThread extends Thread {
public static final int THREAD_EXETUING = 1004;// 执行中
public static final int THREAD_IDLE = 1005;// 空闲状态
private int status = THREAD_IDLE;// 默认为空闲状态
private ATask task;
private String[] params;
@Override
public void run() {
while (XLooper.getInstance().isLoop()) {
if(task!=null) {
Object object = task.doInBackground(params);
task.doPost(object);
status = THREAD_IDLE;
task.updateStatus(ATask.TASK_COMPLETE);
Log.d("tag", "一个任务已完成");
task = null;
XLooper.getInstance().loop();
}
}
}
/**
* 插入任务
*
* @param task
*/
public void insert(ATask task, String... params) {
this.task = task;
if (params != null) {
this.params = params;
}
status = THREAD_EXETUING;
task.updateStatus(ATask.TASK_EXECUTING);
}
/**
* 刷新状态
*/
public void updateStatus(int status) {
this.status = status;
}
/**
* 获取线程状态
*
* @return
*/
public int getStatus() {
return status;
}
}
用法:
新建任务
/**
* 主题:
*/
public class Task extends ATask {
@Override
public Object doInBackground(String... params) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
public void doPost(Object object) {
super.doPost(object);
}
}
其次使用即可
Task task=new Task();
task.execute();
本次实例编写也有很多没有完善的地方,比如空线程超时回收等.