简单线程管理 - Java - Android

8
我有一个应用程序,当用户请求过滤图像时会生成一个新线程。这是我唯一的任务类型,并且所有任务同等重要。
如果我请求太多并发线程(最多只需要9个),线程管理器会抛出RejectedExecutionException异常。
目前我的做法是;
// Manage Concurrent Tasks
private Queue<AsyncTask<Bitmap,Integer,Integer>> tasks = new LinkedList<AsyncTask<Bitmap,Integer,Integer>>();

@Override
public int remainingSize() {
    return tasks.size();
}

@Override
public void addTask(AsyncTask<Bitmap, Integer, Integer> task) {
    try{
        task.execute(currentThumbnail);
        while(!tasks.isEmpty()){
            task = tasks.remove();
            task.execute(currentThumbnail);
        }
    } catch (RejectedExecutionException r){
        Log.i(TAG,"Caught RejectedExecutionException Exception - Adding task to Queue");
        tasks.add(task);
    }
}

只需将被拒绝的任务添加到队列中,下一次启动线程时会检查队列是否有积压。

显然存在一个问题,如果最后一个任务在第一次尝试时被拒绝,它将永远不会重新启动(直到不再需要为止)。

我想知道是否有一个简单的模型可用于管理这种情况。我需要任务在完成时通知队列。

3个回答

12
RejectedExecutionException的原因是因为AsyncTask实现了自己的线程池(如Martelli先生的回答所述),但该线程池最多只能同时处理10个任务。至于为什么有这个限制,我不清楚。
因此,一种可能性是克隆AsyncTask,提高限制(或使用LinkedBlockingQueue无界限制),并使用您的克隆版本。然后,也许可以将更改作为补丁提交给AsyncTask以供未来Android发布使用。
单击此处运行Google代码搜索AsyncTask——第一个命中应该是实现。
如果您只想提高限制,请将MAXIMUM_POOL_SIZE调整为所需大小。如果您想去除限制,请使用零参数的LinkedBlockingQueue构造函数,而不是目前使用的构造函数。据我所知,其余代码可能保持不变。

15
限制不再是10个了。这一限制之所以被设置,是因为AsyncTask并不适合同时启动多个任务。由于这种任务的目标是更新用户界面,如果有许多线程导致更新,则会非常糟糕。请注意,这里的“异步任务”指的是Android开发中的类。 - Romain Guy
目前限制为5个并行线程,参见http://google.com/codesearch#uX1GffpyOZk/core/java/android/os/AsyncTask.java。 - Grantland Chew
@Grantland Chew:不,一开始是5。它可以增长到更多。 - CommonsWare

3

看起来您已经实现了一个版本的线程池设计模式 -- 维基百科文章指向了许多有关该主题的有用文章,这些文章可能会帮助您完善自己的实现。我还推荐这篇针对Java的文章,其中有清晰的代码和解释。


0
也许一种选择是将任务等待在一个阻塞队列(位图队列)上,而不是将位图作为参数传递,但您需要添加一种方法来终止任务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接