ThreadPoolExecutor в Java ME

от
Java

Для выполнения асинхронного кода программисту приходится создавать новый поток и переопределять метод run. Но что будет, если мы захотим выполнить 10, 100, 1000 задач? В этом случае на каждую задачу будет создан новый поток, и всё больше и больше времени система будет не на выполнение каждой задачи непосредственно, а на создание и уничтожение потоков и на переключение между ними, и таким образом мы можем потерять в производительности приложения даже больше, чем однопоточный вариант программы.
Чтобы избежать подобной проблемы, используется следующая идея: пусть некий объект создаст за нас некоторое количество потоков и хранит очередь задач, Любой свободный в данный момент времени поток извлекает из очереди задачу и исполняет её; во время выполнения задачи поток считается занятым, а после завершения - свободным и готовым к выполнению следующей задачи. Такой объект называется ThreadPoolExecutor. Этот класс присутствует в большой Яве, но его нет в Java ME, поэтому далее мы реализуем свой простой ThreadPoolExecutor.
1. Очередь задач
В Java ME нет класса для представления очереди, поэтому создадим свою реализацию на основе Vector'а:
Открыть спойлер
2. ThreadPoolExecutor
Исходный код:
Открыть спойлер
Некоторые комментарии к коду:
- В конструктор мы передаём число - количество потоков, которое должно быть в пуле потоков. Затем каждый поток запускается и выполняет ThreadPoolExecutor.run();
- Код в методе ThreadPoolExecutor.run() - это бесконечный цикл, в котором проверяется наличие задач в очереди. Если задачи есть - поток извлекает задачу и выполняет её, в противном случае поток вызывает у очереди метод wait() и засыпает до тех пор, пока в очереди не окажется очередная задача.
- Поток засыпает в цикле, а не просто по условию
  1. ...
  2. while(taskQueue.isEmpty()) taskQueue.wait();
  3. ...
чтобы избежать ложных пробуждений. Подробнее о них можно почитать здесь: http://src-code.net/nikogda-ne-vyzyvajte-metod-wait-vne-cikla/
- Когда добавляется новая задача, вызывается метод notify() очереди задач, чтобы разбудить какой-нибудь незанятый заснувший поток.
3. Демо.
Для демонстрации работы ThreadPoolExecutor был взят пример из статьи AsyncTask в Java ME. В меню добавлены два пункта с суффиксом "(Thread pool)". Пример можно посмотреть в прикреплённом архиве.
  AsyncExample.zip
  • +9
  • views 6560