Нативная разработка мобильных приложений


Запуск задачи в фоновом потоке



Download 3,69 Mb.
Pdf ko'rish
bet96/228
Sana21.07.2022
Hajmi3,69 Mb.
#834838
1   ...   92   93   94   95   96   97   98   99   ...   228
Bog'liq
Нативная разработка мобильных приложений

Запуск задачи в фоновом потоке
Так как же выполнить работу вне основного потока? Делается это довольно 
просто. Как мы уже говорили, нужно создать новый экземпляр 
Thread
, выпол
-
нить некоторую работу в методе 
run
экземпляра 
Runnable
, переданного кон
-
структору, и запустить поток вызовом 
start
:
Java
new Thread(() -> Log.d("MyTag", "This log is from a background thread")).start();
Kotlin
Thread({Log.d("MyTag", "This log is from a background thread")}).start()
Вот и все! Существует также ряд вспомогательных классов, упрощающих 
управление потоками, в том числе 
ThreadPoolExecutor
и 
Executors
(последний со
-
держит ряд статических функций, которые обычно возвращают готовые к ис
-


142

Конкурентное (многопоточное) выполнение
пользованию экземпляры 
ThreadPoolExecutor
). Использование пула потоков 
позволяет контролировать объем работы, выполняемой в фоновом режиме, 
а также ставить задачи в очередь и удаляет их по мере выполнения. Загляните 
в документацию с описанием 
ThreadPoolExecutor
(
https://oreil.ly/9pV5G
) и 
Execu­
tors
(
https://oreil.ly/
WKIRY
).
Возможно, вы слышали, что конкурентное выполнение – это один из самых 
сложных аспектов в информатике, и мы не будем притворяться, что в нем нет 
ничего чрезвычайно сложного, но большинство из этих сложностей спрятаны 
от нас за фасадом системы или легко обходятся стороной. Как-то Майк (один 
из авторов книги) сказал, что «многопоточность реализуется просто; сложнее 
реализовать синхронизацию». То есть, как было показано выше, мы легко мо
-
жем запустить некоторую задачу в фоновом потоке, но за этим утверждением 
следует 3500 звездочек (извините за гиперболу). Например, в Android нельзя 
получить доступ ни к какому экземпляру 
View
, кроме как из основного потока. 
Это действительно создает большие сложности! В методе 
Runnable.run
нельзя 
даже 
ссылаться
на экземпляр 
View
без риска получить 
RuntimeException
. Кроме 
того, порядок завершения фоновых потоков никак не гарантируется; и здесь 
мы начинаем вдаваться в сложности конкурентного выполнения – байт-код, 
который генерирует компилятор Java, не всегда выглядит так же, как исходный 
код на Java.
Вот классический пример «небезопасного» потока выполнения:
Java
public class MainAc ti vi ty extends Ac ti vi ty {
private static final int MAX = 1000;
private int mCounter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // имеется представление с кнопкой
findViewById(R.id.button).setOnClickListener(view ­> {
while (mCounter < MAX) {
new Thread(() ­> {
Log.d("MyTag", String.valueOf(mCounter++));
}).start();
}
});
}
}
Kotlin
class MainAc ti vi ty : Ac ti vi ty() {
private const val MAX = 1000
private var counter: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) // имеется представление с кнопкой


Android 

143
findViewById(R.id.button).setOnClickListener {
while (counter < MAX) {
Thread { Log.d("MyTag", counter++.toString()) }.start()
}
}
}
}
В зависимости от особенностей устройства и окружения может потребовать
-
ся запустить больше или меньше параллельных задач, чтобы увидеть эффект, 
но, поэкспериментировав с этой простой задачей, вы рано или поздно увиди
-
те, что окончательное значение в журнале 
не равно
9999. Но не будем тратить 
ваше и наше время на объяснение нюансов безопасности многопоточного вы
-
полнения и сразу скажем, что байт-код оператора инкремента выглядит при
-
мерно так:
1) получить значение 
mCounter
из памяти;
2) прибавить 1 к значению 
mCounter
;
3) записать результат обратно в память.
Поскольку система быстро-быстро переключает параллельные потоки, что
-
бы сымитировать параллельное выполнение операций (это называется «пере
-
ключением контекста»), поток № 391 может прочитать значение 
mCounter
в тот 
момент, когда поток № 390 уже выполнил шаг 1, но еще не выполнил шаг 2. Эта 
конкретная ситуация называется состоянием гонки. Данная проблема широко 
известна как взаимовлияние потоков и является одним из примеров недоста
-
точной безопасности при многопоточном выполнении. Это далеко неполное 
исследование рисков конкурентного программирования – некоторые реали
-
зации Java позволяют потокам создавать копии переменных, чтобы избежать 
дорогостоящих вызовов IPC (Interprocess Communication – межпроцессные 
взаимодействия), поэтому, когда несколько потоков изменяют один и тот же 
экземпляр объекта, его состояние не может быть гарантировано.
Для борьбы с этим эффектом существуют специальные механизмы, та
-
кие как ключевые слова 
synchronized
и 
volatile
и классы 
Atomic
. И поскольку 
структуры данных особенно уязвимы (представьте, что один поток выполняет 
обход содержимого структуры данных, а другой добавляет или удаляет эле
-
менты к ней), некоторые структуры имеют потокобезопасные (и менее произ
-
водительные) версии или вспомогательные методы, помогающие уменьшить 
риски.
Более глубокое обсуждение проблем конкурентного выполнения выходит за 
рамки этой главы. Могут потребоваться годы, чтобы освоить многопоточное 
программирование даже в одном технологическом стеке. Некоторые разра
-
ботчики никогда по-настоящему не понимают, что происходит за кулисами, 
и это нормально! Потрясающий разработчик пользовательского интерфейса 
может использовать совершенно иные приемы конкурентного программиро
-
вания, чем программист, работающий с большими данными. Один простой 
трюк в Android заключается в том, чтобы запустить вычисления в фоновом 
потоке, а затем вызвать 
Ac ti vi ty.runOnUiThread

View.post
или 
Handler.post
, дабы 
передать результаты в основной поток, чтобы гарантировать последователь
-
ное выполнение и невосприимчивость к действиям других процессов.



Download 3,69 Mb.

Do'stlaringiz bilan baham:
1   ...   92   93   94   95   96   97   98   99   ...   228




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish