簡體   English   中英

如何在Android中管理Runnable任務的隊列

[英]How to Manage Queue of Runnable Tasks in Android

我有多個任務/ Runnable(即從互聯網下載圖像),這是在用戶滾動瀏覽Android應用程序中的列表時生成的。

我無法控制一次生成多少個任務/ Runnable,這可能在100個。但我想並行執行n(10)個任務。 所以,我打算構建一個設計,只要生成一個新任務/ runnable,它就會被添加到隊列( List<Runnable> )並通過Executors.newFixedThreadPool(10) ,我將只執行前10個並行運行任務。 現在,一旦任務/ Runnable完成,我應該能夠從隊列中刪除它們( List<Runnable> ),並且應該能夠在FIFO中執行隊列中的新任務/ Runnable。

我有兩個類用於此設計。 首先是ExecutorManager ,它是一個單例類,管理10個並行任務的執行,第二個是ImageDownloader類,它實現了runnable並負責下載圖像。 我不確定通知ExecutorManager任務/下載完成的最佳方法是什么,它可以從隊列中執行新任務。 我正在關注FIFO,所以我將始終從隊列中的前10個任務開始執行,但是我將如何知道哪個任務已完成以及哪個任務要從隊列中刪除?

public class ImageDownloader implements Runnable{

    DownloadListener mDownloadListener;

    public ImageDownloader(DownloadListener mDownloadListener, String URL){
        this.mDownloadListener = mDownloadListener;
    }


    @Override
    public void run() {
        //Download the Image from Internet
            //ToDo
        //if Success in download
            mDownloadListener.onDownloadComplete();
        //if Error in download
            mDownloadListener.onDownloadFailure();
        //Inform the Executor Manager that the task is complete and it can start new task
         incrementCount();
    }

    private static synchronized void incrementCount(){
        ExecutorManager.getInstance().OnTaskCompleted();// is there a better way to do it
    }
}



public class ExecutorManager {

    private static ExecutorManager Instance;
    ExecutorService executor = Executors.newFixedThreadPool(Constants.NumberOfParallelThread);
    ArrayList<Runnable> ExecutorQueue = new ArrayList<Runnable>();
    int ActiveNumberOfThread = 0;

    private ExecutorManager(){
    }

    public static ExecutorManager getInstance(){

        if(Instance==null){
            Instance = new ExecutorManager();

        }
        return Instance;
    }

    private void executeTask(){
        if(ExecutorQueue.size()>0 && ActiveNumberOfThread < Constants.NumberOfParallelThread){
            ++ActiveNumberOfThread;
            executor.execute(ExecutorQueue.get(0));//Execute the First Task in Queue
        }
    }

    public void enQueueTask(Runnable Task){

        ExecutorQueue.add(Task);
        executeTask();
    }

    public void removeFromQueue(){
        //How to know, which task to remove?
        ExecutorQueue.remove(0);
    }

    public void OnTaskCompleted(){
        --ActiveNumberOfThread;
        removeFromQueue();
        executeTask();
    }

}

嗯,你很幸運。 您不必告訴ExecutorManager任何東西。 帶有BlockingQueueExecutorService為您處理隊列。 您所要做的就是將Runnable提交給ExecutorService。 它會堅持下去。 如果有任何打開的線程,它將立即運行它。 否則,它將等待其他Runnables完成執行。 一旦完成,它將采取下一個。

如果你看一下源代碼執行人#的newFixedThreadPool ,它實際上只是創建一個ThreadPoolExecutor使用nThreads由支持線程LinkedBlockingQueue像這樣:

public static ExecutorService newFixedThreadPool(int nThreads) {
         return new ThreadPoolExecutor(nThreads, nThreads,
                                       0L, TimeUnit.MILLISECONDS,
                                       new LinkedBlockingQueue<Runnable>());
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM