我有多个任务/可运行(即从互联网下载图像),它们是当用户滚动 Android 应用程序中的列表时生成的。
我无法控制一次生成多少个任务/Runnable,这可能是 100 个。但我只想并行执行 n(10) 个任务。因此,我计划构建一个设计,一旦生成新任务/可运行,它将被添加到队列中(List<Runnable>
)并通过Executors.newFixedThreadPool(10)
,我将仅并行执行前 10 个可运行任务。现在,一旦任务/可运行完成,我应该能够将它们从队列中删除(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 任何内容。一个ExecutorService
with a BlockingQueue
为您处理队列。您所要做的就是提交Runnable
到ExecutorService。它会坚持下去。如果有任何打开的线程,它将立即运行。否则,它将等待直到另一个Runnables
执行完毕。完成后,将进行下一个。
如果你查看源代码执行器#newFixedThreadPool http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/Executors.java#Executors.newFixedThreadPool%28int%29,它实际上只是创建了一个ThreadPoolExecutor
with nThreads
由 a 支持的线程LinkedBlockingQueue
像这样:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)