Android线程池学习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QQ243223991/article/details/52023149

在学习线程池之前需要先了解几个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();


本次实例编写也有很多没有完善的地方,比如空线程超时回收等.

猜你喜欢

转载自blog.csdn.net/QQ243223991/article/details/52023149