Простое управление потоками - Java - Android - PullRequest
8 голосов
/ 13 июня 2009

У меня есть приложение, которое порождает новый поток, когда пользователь запрашивает изображение для фильтрации.

Это единственное задание, которое у меня есть, и все они одинаково важны.

Если я запрашиваю слишком много одновременных потоков (максимум, которое я когда-либо хочу - 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 голосов
/ 14 июня 2009

Причина RejectedExecutionException заключается в том, что AsyncTask реализует собственный пул потоков (согласно ответу г-на Мартелли), но ограниченный максимум 10 одновременными задачами. Почему у них такой предел, я понятия не имею.

Следовательно, есть одна возможность для вас клонировать AsyncTask, повысить лимит (или выйти неограниченным, что также возможно с LinkedBlockingQueue) и использовать ваш клон. Затем, возможно, отправьте изменения в виде патча на AsyncTask для будущих выпусков Android.

Нажмите здесь , чтобы запустить поиск кода Google для AsyncTask - первым хитом должна стать реализация.

Если вы просто хотите поднять лимит, настройте MAXIMUM_POOL_SIZE так, чтобы он был настолько большим, насколько это возможно. Если вы хотите остаться неограниченным, используйте конструктор с нулевым аргументом LinkedBlockingQueue вместо того, который используется в настоящее время. AFAICT, остальная часть кода, вероятно, остается прежней.

3 голосов
/ 13 июня 2009

Похоже, вы реализовали версию шаблона проектирования Thread Pool - статья в википедии указывает на множество полезных статей по этому вопросу, которые могут помочь вам усовершенствовать вашу реализацию. Я также рекомендую эту специфичную для Java статью , которая содержит четкий код и пояснения.

0 голосов
/ 17 февраля 2010

Возможно, вариант заключается в том, чтобы задача ожидала в очереди блокировки (из растровых изображений) вместо того, чтобы принимать растровое изображение в качестве параметра, но вам нужно будет добавить способ завершения задачи (ий).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...