简单的线程管理 - Java - Android

Posted

技术标签:

【中文标题】简单的线程管理 - Java - Android【英文标题】:Simple Thread Management - Java - Android 【发布时间】:2010-11-02 17:17:23 【问题描述】:

我有一个应用程序,当用户要求过滤图像时会产生一个新线程。

这是我唯一的任务类型,所有任务都同等重要。

如果我要求太多并发线程(我想要的最大线程数是 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);
    

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

这样做的明显问题是,如果最终任务在第一次尝试时被拒绝,它将永远不会重新启动(直到不再需要它之后)。

只是想知道是否有一个简单的模型可以用来管理这类事情。我需要任务完成后通知队列。

【问题讨论】:

【参考方案1】:

RejectedExecutionException 的原因是因为AsyncTask 实现了自己的线程池(根据 Martelli 先生的回答),但其上限为最多 10 个同时任务。为什么他们有这个限制,我不知道。

因此,一种可能性是您克隆AsyncTask,提高限制(或无限制,LinkedBlockingQueue 也可以),然后使用您的克隆。然后,也许可以将更改作为补丁提交给AsyncTask,以供将来的 android 版本使用。

点击here 对AsyncTask 运行Google 代码搜索——第一个命中应该是实现。

如果您只是想提高限制,请将MAXIMUM_POOL_SIZE 调整为您可能需要的大小。如果您想不受限制,请使用零参数 LinkedBlockingQueue 构造函数,而不是当前使用的构造函数。 AFAICT,其余代码可能保持不变。

【讨论】:

限制不再是 10。设置了限制是因为 AsyncTasks 不应该被一打解雇。由于此类任务的目标是更新 UI,因此有数十个线程导致更新将非常糟糕。 根据google.com/codesearch#uX1GffpyOZk/core/java/android/os/…目前限制为5个并行线程 @Grantland Chew:不,从 5 开始。它可以超越这个范围。【参考方案2】:

您似乎已经实现了Thread Pool 设计模式的一个版本——***文章指出了许多关于该主题的有用文章,它们可能会帮助您改进您的实现。我也推荐this Java-specific article,它有清晰的代码和解释。

【讨论】:

【参考方案3】:

也许一个选项是让任务在阻塞队列(位图)上等待,而不是将位图作为参数,但您必须添加一种方法让任务终止。

【讨论】:

以上是关于简单的线程管理 - Java - Android的主要内容,如果未能解决你的问题,请参考以下文章

一文简单理解Java线程池的问题

Android A/B system - bootctrl

Android A/B system - bootctrl

java线程池

多线程——Java线程池原理深入

java 线程池socket实现简单http服务器