[英]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任何東西。 帶有BlockingQueue
的ExecutorService
為您處理隊列。 您所要做的就是將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.