1. 程式人生 > >Android執行緒池學習

Android執行緒池學習

在學習執行緒池之前需要先了解幾個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();


本次例項編寫也有很多沒有完善的地方,比如空執行緒超時回收等.