简单线程管理 - Java - Android

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/990948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:42:42  来源:igfitidea点击:

Simple Thread Management - Java - Android

javaandroidmultithreading

提问by gav

I have an application which spawns a new thread when a user asks for an image to be filtered.

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

This is the only type of task that I have and all are of equal importance.

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

If I ask for too many concurrent threads (Max I ever want is 9) the thread manager throws a RejectedExecutionException.

如果我要求太多的并发线程(我想要的最大值是 9),线程管理器会抛出RejectedExecutionException

At the minute what I do is;

目前我所做的是;

// 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);
    }
}

Simply add the rejected task to a queue and the next time a thread is started the queue is checked to see if there is a backlog.

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

The obvious issue with this is that if the final task gets rejected on its first attempt it will never be restarted (Until after it's no longer needed).

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

Just wondering if there's a simple model I should use for managing this sort of thing. I need tasks to notify the queue when they are done.

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

回答by CommonsWare

The reason for the RejectedExecutionExceptionis because AsyncTaskimplements a thread pool of its own (per Mr. Martelli's answer), but one that is capped at a maximum of 10 simultaneous tasks. Why they have that limit, I have no idea.

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

Hence, one possibility is for you to clone AsyncTask, raise the limit (or go unbounded, which is also possible with LinkedBlockingQueue), and use your clone. Then, perhaps, submit the change as a patch to AsyncTaskfor future Android releases.

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

Click hereto run a Google Code Search for AsyncTask-- the first hit should be the implementation.

单击此处运行 Google 代码搜索AsyncTask——第一个命中应该是实现。

If you just want to raise the limit, adjust MAXIMUM_POOL_SIZEto be as big as you're likely to need. If you want to go unbounded, use the zero-argument LinkedBlockingQueueconstructor instead of the one being presently used. AFAICT, the rest of the code probably stays the same.

如果您只想提高限制,请MAXIMUM_POOL_SIZE根据您可能需要的大小进行调整。如果您想无界,请使用零参数LinkedBlockingQueue构造函数而不是目前使用的构造函数。AFAICT,其余的代码可能保持不变。

回答by Alex Martelli

You seem to have implemented a version of the Thread Pooldesign pattern -- the wikipedia article points to many helpful articles on the subject, which may help you refine your implementation. I also recommend this Java-specific articlewhich has clear code and explanation.

您似乎已经实现了线程池设计模式的一个版本——维基百科文章指向了许多关于该主题的有用文章,它们可能会帮助您完善您的实现。我还推荐这篇 Java 特定的文章,它有清晰的代码和解释。

回答by tip

Maybe an option is to have the task wait on a blocking queue (of bitmaps) instead of taking bitmap as a parameter, but you will have to add a way for the task(s) to terminate.

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