Подтвердить что ты не робот

HandlerThread vs Executor - Когда еще один подход к другому?

Мне просто интересно, есть ли времена, когда я должен выбрать Executor над HandlerThread. Есть ли времена, когда один превосходит другого, или я должен просто придерживаться HandlerThread? В моем случае я в настоящее время слушаю ServerSocket для соединений и обрабатываю каждый запрос в отдельном потоке, созданном Executor. Несмотря на то, что я привел конкретный пример, я действительно ищу случаи, когда один из них более уместен, чем другой. Тем не менее, я приветствую комментарии о моем дизайне.

4b9b3361

Ответ 1

Класс Executor более мощный и может использовать пул потоков, тогда как каждый обработчик ссылается на один поток. Исполнитель позволяет вам выполнять все запланированные задачи и отменить их, если хотите. Обработчик, с другой стороны, не будет отвечать на простые вопросы, например, сколько задач ждет или даст мне ссылку на все задачи ожидания. Я считаю, что одна из причин того, что Handler более ограничена, заключается в том, что Android дает вам доступ к основному обработчику, который он использует для пользовательского интерфейса, и вы действительно можете испортить ОС, если вы начали отменять задачи ОС.

В общем, если вам нужен пул потоков или много энергии, используйте Исполнитель. Если вам просто нужен хороший фоновый поток для запуска одной задачи за раз, используйте Handler. В качестве примера, когда я хочу запросить мою базу данных, я просто хочу, чтобы один запрос возникал одновременно, и я не хочу генерировать ANR, поэтому я использую обработчик, работающий в фоновом потоке, чтобы запускать мои запросы.

Я считаю, что ваш выбор исполнителя звучит правильно, так как вы хотите обрабатывать несколько входящих запросов одновременно, и обработчик может делать только одно за раз.

UPDATE: как создать обработчик, который работает в фоновом потоке:

В вашем конструкторе или onCreate напишите следующее, очевидно, что вы можете установить приоритет по своему усмотрению:

public class MyClass {

    private Handler mBgHandler;

    public MyClass() {
        HandlerThread bgThread = new HandlerThread("My-Background-Handler");
        bgThread.start();
        mBgHandler = new Handler(bgThread.getLooper());
    }
}

ОБНОВЛЕНИЕ: не забудьте оставить() или quitSafely() ваш HandlerThread, когда вы закончите с ним, иначе он останется в ожидании навсегда

Ответ 2

Я не буду следовать образцу кода в ответе satur9nine по состоянию на 2011-Dec-22.

Thread.MIN_PRIOROTY сопоставляется с android.os.Process.THREAD_PRIORITY_LOWEST. Цитата:

Самый низкий доступный приоритет потока. Только для тех, кто действительно, действительно не хочет бегать, если что-то еще происходит.

Я бы хотя бы использовал android.os.Process.THREAD_PRIORITY_BACKGROUND, например:

HandlerThread bgThread = new HandlerThread("handler name");
Process.setThreadPriority(bgThread.getThreadId(), Process.THREAD_PRIORITY_BACKGROUND);
bgThread.start();
mBgHandler = new Handler(bgThread.getLooper());

Это присваивает приоритет фонового изображения Android по умолчанию для потока.

В настоящее время потоки приоритета Process.THREAD_PRIORITY_BACKGROUND и ниже разделяют искусственно ограниченное количество процессорного времени с помощью Linux-группы, см., например, здесь. Если фоновая задача не просто ждет ввода-вывода, но и выполняет реальные вычисления, я бы подумал об увеличении своего приоритета с помощью android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE, который (в настоящее время) перемещает его из фоновой группы, но по-прежнему не представляет угрозы для пользовательского интерфейса и в режиме реального времени.

Обновление:. Ответ Satur9nine был полностью изменен в 2013-янв-08, чтобы не установить самый низкий приоритет. Теперь у HandlerThread подразумевается приоритет android.os.Process.THREAD_PRIORITY_BACKGROUND. Это означает, что теперь он получает приоритет фоновой задачи по умолчанию, но он по-прежнему ограничен потреблением искусственного максимума в 10% времени процессора вместе со всеми другими фоновыми задачами, которые могут существовать. Если это нежелательно, используйте мой код выше, например. с

Process.setThreadPriority(bgThread.getThreadId(),
                          Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);

чтобы снять фоновый поток из группы.