Mobil ishlanmada Deadlock: bu nima, kelib chiqish sabablari va o‘zaro blokirovkadan qochish usullari

Muallif: IT Sectr Nashr etilgan: 2026-03-18 O'qish vaqti: 10 daq

Deadlock (o‘zaro blokirovka) — bu ikki yoki undan ortiq oqimlarning boshqa ishtirokchilar tomonidan egallangan resurslarning bo‘shatilishini cheksiz kutish holatidir. Oracle Java Tutorials (2024)-ga ko‘ra, Deadlock aylanma kutishda yuzaga keladi, har bir oqim boshqa oqimga kerakli blokirovkani ushlab turadi. Maxsus aniqlash vositalarisiz, Deadlock ilovaning ishlashini ko‘rinadigan xatolarsiz to‘liq to‘xtatadi.

Muhim fikrlar

  • Deadlock — oqimlarning o‘zaro blokirovkasi, har biri boshqa oqim egallagan resursni kutadi
  • To‘rt shart Coffman (Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait) Deadlock yuzaga kelishi uchun zarur
  • Deadlock farqlanadi Starvation-dan, oqimlar bloklanmagan, balki aylanma bog‘liqlikda faol kutadi
  • Thread Dump — JVM va Android Runtime-da Deadlock aniqlashning asosiy vositasi
  • Blokirovkalar ierarxiyasi va resurslarni egallashning yagona tartibi — o‘zaro blokirovkalarning oldini olishning asosiy usuli

Deadlock nima?

Deadlock (o‘zaro blokirovka) — ko‘p oqimli dasturlashda ikki yoki undan ortiq oqim bir-birini abadiy bloklaydigan holatdir. Har bir oqim boshqa oqimga kerakli resursni ushlab turadi va uni bo‘shatmaydi, yetishmayotgan resursni egallashni kutadi. Natijada, oqimlarning hech biri ishlashni davom ettira olmaydi.

Mobil ishlanmada Deadlock ayniqsa tanqidiydir, chunki u istisno yoki qulashlarga sabab bo‘lmaydi. Ilova shunchaki foydalanuvchi harakatlariga javob berishni to‘xtatadi (ANR — Application Not Responding) va yagona chiqish yo‘li — jarayonni majburiy tugatish. Google ma’lumotlariga ko‘ra (Android Performance Patterns, 2023), Google Play Console-dagi ANR hisobotlarining taxminan 15% fon oqimlaridagi o‘zaro blokirovkalar bilan bog‘liq.

Deadlock-ning boshqa raqobat muammolaridan asosiy farqi — uning tashqi aralashuvsiz qaytarilmasligi. Oqimlar resurslarni o‘z-o‘zidan bo‘shatmaydi, chunki operatsion tizim rejalashtiruvchisi blokirovkani majburiy qaytarib ololmaydi. Bu Deadlock-ni Livelock-dan farqlaydi, bu erda oqimlar faol, ammo foydali ish bajarmaydilar.

Deadlock yuzaga kelish shartlari

1971 yilda Edward G. Coffman Deadlock yuzaga kelishi uchun zarur bo‘lgan to‘rt majburiy shartni shakllantirdi. Agar ulardan hech bo‘lmasa biri bo‘lmasa, o‘zaro blokirovka mumkin emas. Bu shartlar Coffman shartlari sifatida tanilgan va barcha Deadlock oldini olish algoritmlarining asosini tashkil qiladi.

O‘zaro istisno (Mutual Exclusion)

Resurs har bir momentda faqat bitta oqim tomonidan egallanishi mumkin. Agar resurs bir necha oqim tomonidan bir vaqtda o‘qishga ruxsat bersa (masalan, o‘qish rejimida ReadWriteLock), Deadlock yuzaga kelmaydi. Bu shart Mutex va blokirovkalarning tabiatidan kelib chiqadi.

Ushlab turish va kutish (Hold and Wait)

Oqim allaqachon egallangan resursni ushlab turadi va bir vaqtda boshqa resursni egallashni kutadi. Agar oqim joriy resursni keyingi resursni so‘rashdan oldin bo‘shatishi mumkin bo‘lsa (ikki fazali blokirovka orqali), Hold and Wait sharti buziladi. Android-da bu ko‘pincha oqim ma’lumotlar bazasi blokirovkasini ushlab, SharedPreferences blokirovkasini egallashga harakat qilganda namoyon bo‘ladi.

Majburiy tortib olishning yo‘qligi (No Preemption)

Operatsion tizim blokirovkani oqimdan majburiy qaytarib ololmaydi. Resurs faqat oqim uni o‘zi bo‘shatganda ozod qilinadi. Ba‘zi tizimlarda (masalan, SQLite WAL rejimi) alohida operatsiyalar darajasida majburiy tortib olish joriy qilingan, bu Deadlock xavfini kamaytiradi.

Aylanma kutish (Circular Wait)

Har biri zanjirdagi keyingi oqim tomonidan ushlab turilgan resursni kutayotgan yopiq oqim zanjiri mavjud. Masalan, oqim A resurs 1-ni ushlab turadi va resurs 2-ni kutadi, oqim B resurs 2-ni ushlab turadi va resurs 1-ni kutadi. Bu dasturchi arxitektura jihatdan bartaraf eta oladigan yagona shartdir — blokirovkalar ierarxiyasi orqali. Agar barcha oqimlar resurslarni qat’iy belgilangan global tartibda egallasa, aylanma jismonan mumkin emas.

Amalda, Android ilovalarida Deadlock ko‘pincha turli darajadagi blokirovkalarning yashirin kesishishi tufayli yuzaga keladi: ma’lumotlar bazasi blokirovkasi (Room), SharedPreferences blokirovkasi va xotiradagi kolleksiya blokirovkasi. Bu blokirovkalarning har biri turli komponentlar tomonidan boshqariladi va markazlashtirilgan egallash tartibi protokolisiz dasturchilar beixtiyor aylanalar yaratadilar.

Kotlin kodida Deadlock misoli

Keling, o‘zaro blokirovkaning klassik misolini ko‘rib chiqaylik — ikki oqim blokirovkalarni turli tartibda egallaydi. Agar birinchi oqim A resursini bloklab B-ni egallashga harakat qilsa, ikkinchisi esa B-ni bloklab A-ni egallashga harakat qilsa, Deadlock yuzaga keladi.

kotlin
class DeadlockExample {
    private val lockA = Any()
    private val lockB = Any()

    fun operationA() {
        synchronized(lockA) {
            Thread.sleep(50)  // ish simulyatsiyasi
            synchronized(lockB) {
                println("operationA bajarildi")
            }
        }
    }

    fun operationB() {
        synchronized(lockB) {  // teskari tartib!
            Thread.sleep(50)
            synchronized(lockA) {
                println("operationB bajarildi")
            }
        }
    }
}

fun main() {
    val ex = DeadlockExample()
    Thread { ex.operationA() }.start()
    Thread { ex.operationB() }.start()
    // Ilova abadiy qotib qoladi — Deadlock!
}

Ushbu misolda operationA lockA-ni egallaydi, operationB esa lockB-ni. So‘ngra har biri ikkinchi blokirovkani egallashga harakat qiladi — va ikkalasi ham cheksiz kutadi. Dastur xato xabarisiz qotib qoladi. Tuzatishning yagona usuli — barcha metodlarda blokirovkalarni egallashning bir xil tartibini ta’minlash.

Deadlock vs Starvation vs Livelock

Ushbu uch raqobat muammosi ko‘pincha chalkashtiriladi, ammo ularning mexanizmlari va oqibatlari tubdan farq qiladi. Deadlock — to‘liq to‘xtash, Starvation — resursning cheksiz kutishi, Livelock — faol harakatsizlik. Farqlarni tushunish to‘g‘ri bartaraf etish strategiyasini tanlash uchun juda muhimdir.

TavsifiDeadlockStarvationLivelock
Oqimlar holatiBloklangan (BLOCKED)Tayyor (RUNNABLE)Faol (RUNNABLE)
Ish bajarishYo‘qYo‘qHa, ammo foydasiz
SababAylanma kutishAdolatsiz rejalashtirishMojaroni noto‘g‘ri boshqarish
AniqlashThread Dump, vaqt chegaralariTaraqqiyot monitoringiQayta urinishlar hisoblagichi

Starvation (och qolish) rejalashtiruvchi past prioritetli oqimning bajarilishini doimiy ravishda boshqalar foydasiga kechiktirganda yuzaga keladi. Deadlock-dan farqli o‘laroq, oqim bloklanmagan — u bajarishga tayyor, ammo protsessor vaqti olmaydi. Android-da odatiy stsenariy — past prioritetli fon oqimi hech qachon bajarilmaydi, agar UI va Service oqimlari doimiy faol bo‘lsa.

Livelock (faol blokirovka) — oqimlar bloklanmagan, ammo bir-birining harakatlariga cheksiz javob beradigan, foydali ish bajarmaydigan holatdir. Klassik analogiya — ikki kishi koridorda uchrashib, ikkalasi ham bir tomonga harakatlanib, yo‘l berishga urinadi. Deadlock-dan farqli o‘laroq, Livelock-dagi oqimlar CPU iste’mol qiladi, qurilma batareyasini zaryadsizlantiradi.

Deadlock-ni qanday aniqlash mumkin

Thread Dump (oqimlar dumpi) — JVM va Android Runtime-da o‘zaro blokirovkalarni aniqlashning asosiy vositasidir. Dump paytida JVM monitorlar o‘rtasidagi bog‘liqlik grafigini avtomatik tahlil qiladi va Deadlock aylanalarini belgilaydi. Android Studio-da oqimlar dumpini Android Profiler yoki ADB Shell-dan kill -3 PID buyrug‘i orqali olish mumkin.

Ishlash vaqtida Deadlock-ni avtomatik aniqlash Watchdog taymerlari orqali amalga oshiriladi. Agar oqim belgilangan vaqt ichida operatsiyani tugatmasa, watchdog dump boshlanishini tashkil qiladi va hisobotni Crash Reporting tizimiga (Firebase Crashlytics, Sentry) yuboradi. Sentry ma’lumotlariga ko‘ra (Issue Resolution Report, 2024), watchdog sozlamasi Deadlock diagnostika vaqtini haftalardan bir necha soatgacha qisqartiradi.

Ishlab chiqish bosqichida JetBrains-dan ThreadSafe statik analizatori va Lock Checker moduli bilan Checker Framework samarali. Bu vositalar manba kod darajasida blokirovkalarni egallash tartibini tahlil qiladi va potensial aylanalar haqida ogohlantiradi. Qo‘shimcha ravishda, Test-Driven Deadlock Detection — yuzlab oqimlarda turli blokirovka tartiblari bilan operatsiyalarni ishga tushiradigan stress testlar — tavsiya etiladi.

Alohida e’tiborga loyiq Cooperative Deadlock Detection — oqimlar global registr orqali egallangan blokirovkalar haqida ma’lumot almashadigan usuldir. Agar oqim potensial aylana aniqlasa, u barcha resurslarni bo‘shatadi va operatsiyani takrorlaydi. Bu yondashuv taqsimlangan tizimlarda (Apache ZooKeeper, Google Chubby) qo‘llaniladi va Jetpack Sync kabi kutubxonalar orqali asta-sekin mobil ishlanmaga joriy etilmoqda.

O‘zaro blokirovkaning oldini olish usullari

Blokirovkalar ierarxiyasi (Lock Ordering)

Eng ishonchli usul — butun ilovada blokirovkalarni egallashning global tartibini o‘rnatish. Agar barcha oqimlar avval kichik raqamli blokirovkani, so‘ngra katta raqamli blokirovkani egallasa, aylanma kutish (Circular Wait sharti) mumkin emas. Katta loyihalarda tartib hujjatlarda belgilanadi va kod ko‘rib chiqish orqali tekshiriladi.

Vaqt chegarasi bilan TryLock

TryLock — oqimni cheksiz bloklamaydigan, aksincha, blokirovka belgilangan vaqtda olinmasa false qaytaradigan blokirovka usulidir. Java-da bu ReentrantLock.tryLock(timeout, TimeUnit) orqali, Kotlin Coroutines-da vaqt chegarasi bilan Mutex.withLock orqali amalga oshiriladi. Muvaffaqiyatsizlikda, oqim barcha egallangan resurslarni bo‘shatadi va urinishni keyinroq takrorlaydi.

Bankir algoritmi (Banker’s Algorithm)

Bankir algoritmi — Edsger Dijkstra tomonidan taklif qilingan Deadlock oldini olishning nazariy usulidir. U resurslarni taqsimlashni bank operatsiyalari sifatida modellashtiradi: tizim resursni ajratmaydi, agar bu xavfli holatga (deadlock) olib kelishi mumkin bo‘lsa. Amalda algoritm mobil ishlanmada kam qo‘llaniladi, chunki oqimlarning maksimal ehtiyojlarini oldindan bilish murakkab, ammo uning tamoyillari SQLite ma’lumotlar bazalari va fayl tizimlarida qo‘llaniladi.

Tez-tez so‘raladigan savollar

Deadlock bir oqimli ilovada yuzaga kelishi mumkinmi?

Yo‘q, o‘zaro blokirovka uchun kamida ikki oqim kerak. Bir oqimli kodda barcha operatsiyalar ketma-ket bajariladi, shuning uchun aylanma kutish mumkin emas. Biroq Deadlock fayl blokirovkalari yoki jarayonlararo semaforlardan foydalanganda jarayonlar o‘rtasida yuzaga kelishi mumkin.

Kotlin Coroutines-dagi Deadlock oqimlardagi Deadlock-dan nima bilan farq qiladi?

Korutinalarda Deadlock to‘xtatilgan funksiyalar (suspend) darajasida yuzaga keladi va OS oqimini bloklamaydi, bu uni kamroq sezilarli qiladi. kotlinx.coroutines-dan Mutex to‘xtatuvchi (suspending), u oqimni bloklamaydi, ammo korutina bajarilmaydi. Aniqlash uchun kotlinx-coroutines-debug modulidan DebugProbes foydalaning.

Android-da SQLite-dagi Deadlock nima?

SQLite Deadlock ikki ma’lumotlar bazasi ulanishi turli tartibda operatsiyalarni bajarishga harakat qilganda yuzaga keladi. SQLite bunday vaziyatlarni aniqlaydi va SQLITE_BUSY yoki SQLITE_LOCKED xato kodini qaytaradi. Android-da yagona ma’lumotlar bazasi nusxasi va @Transaction orqali operatsiyalar bilan Room-dan foydalanish tavsiya etiladi, bu ulanishlararo Deadlock-ni bartaraf qiladi.

Android Deadlock-ni qanday aniqlaydi?

Android Runtime ANR (Application Not Responding) yaratilganda ishga tushadigan ichki Deadlock detektoriga ega. Tizim ilovaning barcha oqimlarining Thread Dump-ni tahlil qiladi va o‘zaro blokirovkalarni belgilaydi. Natija /data/anr/traces.txt va Google Play Console ning ANR Reports bo‘limida mavjud.

Deadlock ishlab chiqarishda topilsa nima qilish kerak?

Avvalo, ilovaning barcha oqimlarining Thread Dump-ni oling. Har bir oqim qanday blokirovkalarni ushlab turganini va qaysilarini egallashga harakat qilayotganini tahlil qiling. Vaqt chegarasi oshib ketganda avtomatik dump bilan Watchdog taymerini joriy qiling. Tuzatishdan so‘ng, takrorlanishning oldini olish uchun CI quvuriga ThreadSafety lint qoidasini qo‘shing.

Xulosa

  • Deadlock — oqimlarning bir-birining egallagan resurslarini cheksiz kutadigan o‘zaro blokirovkasi
  • To‘rt Coffman sharti (Mutual Exclusion, Hold and Wait, No Preemption, Circular Wait) Deadlock yuzaga kelishi uchun zarur
  • Thread Dump — JVM va Android Runtime-da o‘zaro blokirovkalarni aniqlashning standart usuli
  • Blokirovkalar ierarxiyasi yagona global tartib bilan aylanma kutish shartini to‘liq bartaraf qiladi
  • Vaqt chegarasi bilan TryLock cheksiz kutishning oldini oladi va oqimga resursning mavjud emasligini to‘g‘ri boshqarishga imkon beradi
  • Deadlock vs Starvation — Deadlock-da oqimlar bloklanadi, Starvation-da bajarishga tayyor, ammo CPU olmaydi
  • Watchdog taymerlari va statik analizatorlar (ThreadSafe, Checker Framework) — CI/CD-da Deadlock-dan asosiy himoya

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing