Потоки в процесі Android

&nbsp

AsyncTask і ContentProvider разом утворюють дуже потужну ідіому, яка може бути адаптована до різноманітних видів поширених архітектур додатки Майже будь патерн «Модель-вид-контролер» (MVC), в якому вид опитує модель, може (і, мабуть, повинен) реалізовуватися таким чином Якщо архітектура додатка вимагає, щоб модель відправляла зміни в вид, або в даній архітектурі модель є долгоживущей або працює безперервно, одного тільки AsyncTask може бути недостатньо

Згадаймо основоположне правило обміну даними між потоками У найзагальнішому вигляді це правило дуже обтяжливе Але дослідження AsyncTask, зроблене нами в попередньому підрозділі, демонструє ідіому, яка спрощує правильну координацію конкурентних завдань у Android: складна робота, яка полягає в публікації стану одного потоку і наданні цієї інформації іншому потоку, повністю прихована в реалізації класу-шаблону У той же час в попередньому підрозділі ми додатково загострили увагу на деяких пастках, повязаних з конкурентним програмуванням, в які часто трапляються неуважні розробники Існують і інші безпечні ідіоми, здатні спростити рішення деяких проблем, повязаних з конкурентним програмуванням Одна з цих ідіом – широко застосовувана в Java взагалі – впроваджена під фреймворці Android Іноді її називають привязкою до потоку (thread confinement)

Припустимо, що потік DBMinder створює обєкт і змінює його протягом деякого часу Завершивши роботу, він повинен передати обєкт іншому потоку, DBViewer, для подальшої обробки Для цього DBMinder і DBViewer, що використовують привязку до потоку, повинні спільно використовувати точку скидання обєкта (drop point) і повязану з нею блокування Процес будується таким чином

1 DBMinder захоплює блокування і зберігає посилання на обєкт, що знаходиться в точці скидання

2 DBMi nder знищує всі посилання на обєкт

3 DBMi nder знімає блокування

4 DBViewer захоплює блокування і виявляє в точці скидання посилання на обєкт

5 DBViewer відновлює посилання з точки скидання, а потім очищає цю точку

6 DBViewer знімає блокування

Такий процес працює з будь-яким обєктом, незалежно від того, чи гарантується в самому цьому обєкті безпеку потоків Це обумовлено тим, що поле скидання є єдиним станом, який коли-небудь в ході роботи програми спільно використовується кількома потоками У нашому випадку обидва потоку коректно захоплюють єдину блокування, перш ніж отримати доступ до точки скидання Коли DBMinder завершує роботу з обєктом, він передає обєкт до DBViewer і не зберігає ніяких посилань на цей обєкт: стан переданого обєкта ніколи не використовується спільно декількома потоками

Привязка до потоку – це дивно потужний інструмент Зазвичай реалізації використовують в якості загальної точки скидання впорядковану чергу завдань Кілька потоків можуть одночасно вимагати захоплення блокування, але утримання блокування одним потоком триває не довше, ніж необхідно для постановки завдання в чергу Один або декілька потоків-виконавців захоплюють блокування черги, щоб взяти з неї завдання для виконання Подібний патерн іноді називають «модель постачальник / споживач » (producer / consumer model) Поки фрагмент роботи може виконуватися повністю в контексті потоку-виконавця, що запросив цей фрагмент, подальшої синхронізації не потрібно Уважно вивчивши реалізацію AsyncTask, ви зрозумієте, як саме все це працює

Привязка до потоку настільки корисна, що в Android вона впроваджена в фреймворк системи у вигляді класу під назвою Looper При ініціалізації Looper потік Java перетворюється на чергу завдань Весь свій життєвий цикл він витрачає на взяття завдань з локальної черги і їх виконання Інші потоки ставлять завдання в чергу для обробки з боку ініціалізованих процесу, як показано вище Оскільки потік, що ставить завдання в чергу, видаляє всі посилання на обєкти, які в цю чергу ставить, обидва потоку можна програмувати, не турбуючись про проблеми, повязані з конкурентною обробкою Крім того що такий підхід радикально спрощує коректне написання програм, він ще й усуває неефективне використання ресурсів, яке може бути обумовлене надмірними витратами на синхронізацію

Можливо, це опис черзі завдань нагадує вам про ту концепції, яку ми зачіпали на початку даної глави Однопотоковий подієво-управля-емий користувальницький інтерфейс Android – це, по суті, Looper При запуску Context система виконує деяку реєстрацію, а потім ініціалізує потік запуску як Looper Цей потік стає основним потоком служби та потоком користувача інтерфейсу для активності У активності фреймворк для користувача інтерфейсу зберігає посилання на цей потік, і його черга завдань стає чергою подій користувальницького інтерфейсу: всі зовнішні драйвери, екран, клавіатура, обробник викликів і т д направляють завдання в цю чергу

Друга половина Looper називається Hand er Handl ег, створюваний в потоці Looper, надає портал для черги Looper Коли потік Looper хоче дозволити якомусь іншому потоку, який стоїть у черзі, отримати доступ до черги завдань, він створює новий Handlеr і передає його іншому потоку Щоб спростити роботу з Handler, використовується декілька кодових комбінацій: Viewpost (Runnable), View postDelayedCRunnable, long) і Activity runOnUiThread (Runnable)

У інструментарії Android є ще одна зручна і потужна парадигма, призначена для межпроцессной комунікації та поділу роботи: ContentProvider Перш ніж будувати власну архітектуру, засновану на низькорівневих компонентах, що розглядаються в цьому розділі, подумайте, чи не досить для вирішення що стоїть перед вами завдання звичайного постачальника вмісту Постачальники вмісту – гнучкі і розгортаються компоненти, при цьому паралельне виконання з їх застосуванням протікає у досить швидко у всіх додатках, крім більшості програм, чутливих до затримок (time-sensitive)

Джерело: Android Програмування на Java для нового покоління мобільних пристроїв

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*