Многопоточность UI и не UI потоков

Я использую многопоточность в своих программах. Однако меня смущает то, как многопоточность увеличивает производительность приложения? Насколько мне известно, ОС назначает процессу/приложению один поток. Если вы создадите несколько потоков внутри этого процесса, эти потоки не будут похожи на целую новую группу потоков, назначенных процессу операционной системой. Вместо этого один поток выполняется одновременно, в то время как другой поток ожидает. Я могу ошибаться в этом, поэтому я хотел бы прояснить эту путаницу.

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

ИЗМЕНИТЬ:

Я так понимаю, пока я не передаю Mainthread вместо исполняемого, экземпляр обработчика создаст новый отдельный поток пользовательского интерфейса, который никоим образом не связан с потоком mainUI или вообще не загружает его, верно?

// executes code on mainUI thread thread?
new Handler(Looper.getMainLooper()).post(){
    ....
}
// creates a separate UI thread that isn't related to/executes code on mainUI thread at all, Correct?
new Handler(new Runnable()).post(){
    ....
}

person user2498079    schedule 26.04.2015    source источник


Ответы (3)


как многопоточность увеличивает производительность приложения?

Вообще говоря, это не повышает производительность приложения. Это может решить определенные проблемы с точки зрения UX, например, уменьшить рывки.

Насколько мне известно, ОС назначает процессу/приложению один поток.

Нет, приложение для Android изначально будет иметь несколько потоков, созданных фреймворком. К ним относятся основной поток приложения и пул потоков связывания.

Если вы создадите несколько потоков внутри этого процесса, эти потоки не будут похожи на целую новую группу потоков, назначенных процессу операционной системой.

Да, они.

Вместо этого один поток выполняется одновременно, в то время как другой поток ожидает.

На многоядерном процессоре несколько потоков действительно могут выполняться параллельно. Даже на одноядерных процессорах планировщик Linux (часть ядра Linux, лежащего в основе Android) будет распределять время между потоками.

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

Основной поток приложения (также известный как поток пользовательского интерфейса) по своей сути является просто потоком. Однако именно поток отвечает за отправку событий клавиш и касаний, а также за иное применение обновлений пользовательского интерфейса. Важно не блокировать этот поток, поэтому, если вы работаете в этом потоке (например, onCreate() действий и фрагментов, onClick() виджета, getView() в ListAdapter), вам нужно вернуться очень быстро, в идеале менее миллисекунды. В противном случае у вас есть «jank», определенный в Android как замороженный пользовательский интерфейс, особенно когда пользовательский интерфейс должен анимироваться (например, прокручивать ListView).

Так, например, давайте предположим, что мы хотим загрузить файл, достаточно большой, чтобы его загрузка заняла 10 секунд. Загружаем ли мы файл в основном потоке приложения или в фоновом потоке, это не влияет на общую производительность, так как в любом случае это займет 10 секунд. Однако загрузка в основном потоке приложения приведет к зависанию нашего пользовательского интерфейса на 10 секунд, что сделает пользователей недовольными. Загрузка файла в фоновом режиме позволяет избежать этой проблемы. Обратите внимание, что попытка выполнить сетевой ввод-вывод в основном потоке приложения по умолчанию завершается ошибкой на Android 4.0+ (с NetworkOnMainThreadException), специально для того, чтобы избежать этой конкретной проблемы.

person CommonsWare    schedule 26.04.2015
comment
Доступен ли также пул потоков связующего для потока пользовательского интерфейса? В ПОРЯДКЕ. Так как же потоки Handler(UI) снимают нагрузку с основного потока пользовательского интерфейса, если это единственный поток пользовательского интерфейса? По моему опыту, если моему приложению необходимо выполнить какую-либо задачу пользовательского интерфейса, требующую высокой производительности, и если я сделаю это в основном потоке пользовательского интерфейса, это вызовет рывки. Однако, если я помещу эту задачу в поток обработчика, производительность приложения не пострадает. Почему? - person user2498079; 26.04.2015
comment
@ user2498079: Доступен ли пул потоков связывания также для потока пользовательского интерфейса? -- Я понятия не имею, что вы имеете в виду, извините. Однако, если я помещу эту задачу в поток обработчика, производительность приложения не пострадает. Почему? -- потому что HandlerThread - это отдельный поток. Вы заметите, что HandlerThread является подклассом Thread. Правильно выполненная работа в отдельном потоке не будет блокировать основной поток приложения и уменьшит вероятность зависания. - person CommonsWare; 26.04.2015
comment
Я говорил о [Handler][1] [1]: developer.android. com/reference/android/os/Handler.html Насколько я понимаю, если я не передам Mainthread вместо runnable, экземпляр Handler создаст новый отдельный поток пользовательского интерфейса, верно? - person user2498079; 26.04.2015

  1. Поток и Процесс — это не одно и то же. (смотрите ссылки в конце)

  2. Если на вашем устройстве есть одиночные процессы (одно ядро), то потоки не будут работать параллельно, а будут многократно переключать выполнение, что будет управляться ОС/компилятором.

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


  1. Итак, простыми словами, потоки распределяют нагрузку с одного ядра на несколько ядер, вот как потоки улучшают производительность.

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

  3. Если вас интересуют потоки и параллелизм, прочтите эту книгу, она охватывает все аспекты (Java и Clojure) Семь моделей параллелизма за семь недель


В чем разница между процессом и потоком?< /а>

http://www.programmerinterview.com/index.php/operating-systems/thread-vs-process/

person Community    schedule 26.04.2015

Вы можете запускать потоки параллельно, используя поток / пул exeuter в многоядерном режиме, рабочие потоки используются для выполнения некоторой работы в фоновом режиме, которая может отправлять или не отправлять данные в основной поток для обновления UX. Например, в вашем списке у вас есть изображения большого пальца для каждой строки, если вы не будете использовать отдельные/рабочие потоки, тогда основной поток будет заблокирован. В то время как для миниатюр для каждой строки мы используем параллельные потоки для загрузки изображений и отображения в соответствующей строке, теперь рабочие потоки несут ответственность за загрузку миниатюры, которая может занять секунды, после загрузки этот поток вернет изображение в основной поток и теперь установит изображение в указанное значение. место расположения.

person Haris Qureshi    schedule 26.04.2015