Mobil inkişafda Livelock: bu nədir, qarşılıqlı bloklamadan fərqi və iş prinsipi

Müəllif: IT Sectr Dərc olunub: 2026-03-18 Oxuma vaxtı: 10 dəq

Livelock (aktiv bloklama) — çoxiplikli proqramlaşdırmada iplərin bloklanmadığı, lakin bir-birinin hərəkətlərinə sonsuz reaksiya verərək faydalı iş görmədiyi vəziyyətdir. Baeldung (Java Concurrency Guide, 2024)-a görə, Livelock zamanı iplər qonşu iplərin vəziyyətinə cavab olaraq daim vəziyyət dəyişir, lakin heç biri məqsədə çatmır. Deadlock-dan fərqli olaraq, Livelock 100% CPU sərf edir ki, bu da mobil cihazın batareyasını tez boşaldır.

Əsas məqamlar

  • Livelock — iplərin aktiv olduğu, lakin irəliləmədiyi, münaqişələrə sonsuz reaksiya verdiyi vəziyyət
  • Deadlock-dan fərqli olaraq, Livelock zamanı iplər bloklanmır — onlar daim vəziyyətlər arasında keçid edir
  • Aktiv bloklama prosessor vaxtı və enerji sərf edir, tətbiqin performansını pisləşdirir
  • Təkrar cəhd sayğacı (retry limit) — sonsuz Livelock-un qarşısını almağın ən sadə yolu
  • Təsadüfi gecikmə (exponential backoff) iplər arasında sinxron reaksiya dövrlərini pozur

Livelock nədir?

Livelock (aktiv bloklama) — çoxiplikli sistemdə iplərin bloklanmadığı, lakin faydalı iş də görmədiyi vəziyyətdir. Hər bir ip işi davam etdirə bilmədiyini aşkarlayır və bunu düzəltməyə çalışır, lakin onun hərəkətləri digər iplərdə eyni reaksiyaya səbəb olur. Nəticədə sistem irəliləyiş əldə etmədən sonsuz olaraq vəziyyətlər arasında keçid edir.

Livelock-un klassik analogiyası — dar dəhlizdə iki nəfərin qarşılaşmasıdır. Hər biri yol vermək üçün kənara çəkilir, lakin hər ikisi eyni anda eyni hərəkəti edir və yenə üz-üzə gəlir. Onlar yerində dayanmır (bu Deadlock olardı), aktiv hərəkət edir, lakin yenə də ayrıla bilmir. Proqramlaşdırmada bu, daim resursları boşaldan və yenidən ələ keçirən iplərə uyğun gəlir.

Mobil inkişafda Livelock xüsusilə təhlükəlidir, çünki o, istifadəçi üçün görünməzdir: tətbiq donmur, interfeys bloklanmır, lakin batareya fon iplərinin 100% CPU yükü səbəbindən 2-3 dəfə tez boşalır. Google testlərinə görə (Android Battery Optimization, 2023), fon Service-də Livelock cihazın batareya ilə işləmə müddətini 40% qısalda bilər.

Livelock necə yaranır

Münaqişəyə sinxron reaksiya

Livelock bir neçə ipin eyni münaqişə reaksiya strategiyasından istifadə etdiyi zaman yaranır. Əgər İp A resursu ələ keçirə bilmir və cari resursunu boşaldırsa, İp B də eyni anda eyni şeyi edirsə, hər ikisi dövrü təkrarlayır və vəziyyət sonsuz təkrarlanır. Bu, xüsusilə TryLock və uğursuzluqda avtomatik boşaltma alqoritmləri üçün xarakterikdir.

Təkrar cəhdlərdə təsadüfilik olmaması

İplər təkrar cəhddən əvvəl sabit gecikmədən istifadə etdikdə, sinxron dövrə girə bilərlər. Hər iki ip eyni vaxt gözləyirsə, yenə eyni anda resursu ələ keçirməyə çalışacaq və eyni anda boşaldacaq. Problem, Ethernet-də CSMA/CD alqoritmində olduğu kimi, təsadüfi komponentli (jitter) exponential backoff istifadə edilərək həll olunur.

Sıraların yanlış dizaynı

Mobil inkişafda Livelock tez-tez tapşırıq sıralarının yanlış implementasiyası zamanı yaranır. Məsələn, işçi ip mesajın emalını bitirdikdə, lakin prioritetləşdirmə məntiqinə görə daim nəzarəti eyni şeyi edən başqa bir işçiyə ötürdükdə. Bu hallar qeyri-standart RejectedExecutionHandler siyasəti olan fərdi ThreadPoolExecutor-lar üçün xarakterikdir.

Kotlin kodunda Livelock nümunəsi

İki ipin TryLock istifadə edib uğursuzluqda resursu boşaltdığı bir vəziyyəti nəzərdən keçirək. Aktiv bloklama ona görə yaranır ki, hər iki ip eyni məntiqi tətbiq edir və sinxron olaraq cəhdləri təkrarlayır.

kotlin
import java.util.concurrent.locks.ReentrantLock
import java.util.concurrent.TimeUnit

class LivelockWorker(private val name: String,
                     private val lock1: ReentrantLock,
                     private val lock2: ReentrantLock) {

    fun execute() {
        while (true) {
            if (lock1.tryLock(50, TimeUnit.MILLISECONDS)) {
                if (lock2.tryLock(50, TimeUnit.MILLISECONDS)) {
                    println("$name — yerinə yetirildi!")
                    lock2.unlock()
                    lock1.unlock()
                    return
                } else {
                    lock1.unlock()  // boşaldırıq və təkrar edirik
                }
            }
            Thread.sleep(50)  // sabit gecikmə — Livelock-un əsas amili
        }
    }
}

Əgər iki LivelockWorker nümunəsi lock1 və lock2-ni fərqli sıra ilə ələ keçirməklə işə salınarsa, onlar aktiv bloklamaya girəcəklər. Hər biri birinci resursu ələ keçirəcək, ikincini ala bilməyəcək, birincini boşaldacaq, 50 ms gözləyəcək və təkrarlayacaq — sonsuz, CPU sərf edərək. Düzəliş — gecikməyə təsadüfi komponent (jitter) əlavə etmək və təkrar cəhd sayını məhdudlaşdırmaq.

Düzəldilmiş versiya təsadüfi jitter ilə exponential backoff istifadə edir. Hər uğursuz cəhddən sonra gözləmə müddəti təsadüfi çarpan əlavə edilərək artır, bu da iplər arasında sinxronluğu pozur.

kotlin
fun executeWithBackoff() {
    var delay = 10L
    var attempts = 0

    while (attempts < 5) {
        if (lock1.tryLock(delay, TimeUnit.MILLISECONDS)) {
            if (lock2.tryLock(delay, TimeUnit.MILLISECONDS)) {
                println("Uğur!")
                lock2.unlock(); lock1.unlock()
                return
            }
            lock1.unlock()
        }
        delay = (delay * 2 + (0..50).random())
        attempts++
    }
    println("5 cəhddən sonra alınmadı")
}

Livelock vs Deadlock: əsas fərqlər

Xarici oxşarlığa baxmayaraq, Livelock və Deadlock prinsipial olaraq fərqli mexanizmlərə və nəticələrə malikdir. Deadlock zamanı iplər bloklanır və CPU sərf etmir — tətbiq sadəcə donur. Livelock zamanı iplər aktivdir, 100% CPU sərf edir, lakin faydalı iş görmür. Aradan qaldırma strategiyasının seçimi bloklama növünün düzgün müəyyən edilməsindən asılıdır.

ParametrDeadlockLivelock
İplərin vəziyyətiBLOCKED / WAITINGRUNNABLE
CPU sərfiyyatıMinimalYüksək (90-100%)
Batareya sərfiyyatıAşağıYüksək
AşkarlamaThread DumpCPU Profiler + vizual analiz
Tipik səbəbBloklamaların fərqli ələ keçirmə sırasıMünaqişəyə eyni reaksiya strategiyası
DüzəlişBloklama iyerarxiyasıRetry limit + exponential backoff

Mobil inkişafda praktik fərq çox böyükdür. Deadlock ANR və tətbiqin yenidən başlamasına gətirib çıxarır — Google Play Console vasitəsilə aşkarlanır və bildirilir. Livelock diqqətdən kənar qalır: tətbiq işləyən kimi görünür, lakin batareya bir saata boşalır və istifadəçi sadəcə tətbiqi silir. Firebase Analytics məlumatlarına görə (App Retention Report, 2024), istifadəçilərin 68%-i tətbiqi silir, əgər o fonda həddindən artıq batareya sərf edirsə.

Livelock-u necə aşkar etmək olar

Livelock-un aşkarlanması Deadlock-dan daha çətindir, çünki sistem aşkar siqnallar vermir — istisna yoxdur, ANR yoxdur, səhv mesajları yoxdur. Əsas diaqnostika metodu — CPU Profiler Android Studio-da. Əgər ip daim RUNNABLE vəziyyətindədirsə, lakin faydalı giriş-çıxış və ya hesablama əməliyyatları yerinə yetirmirsə — bu, Livelock şübhəsidir.

Əlavə əlamət — tətbiq boş vəziyyətdə ikən anormal batareya sərfiyyatı. Android Battery Historian (Android SDK tərkibində alət) komponentlər üzrə enerji sərfiyyatı qrafikləri qurur. Əgər CPU Wakelock görünən səbəb olmadan saxlanılırsa — Method Tracing işə salmaq və şübhəli iplərin çağırış stack-lərini təhlil etmək lazımdır.

Kod səviyyəsində təkrar cəhdlərin loglanması threadId və vaxt göstərilməklə kömək edir. Əgər log saniyədə minlərlə təkrar cəhd göstərirsə və heç bir uğur yoxdursa — bu Livelock-dur. Hystrix-ə bənzər circuit breaker və ya hədd aşıldıqda əməliyyatı söndürən və Crashlytics vasitəsilə tərtibatçıya xəbər verən retry sayğacı tətbiq etmək tövsiyə olunur.

Aktiv bloklamanın qarşısını alma üsulları

Təkrar cəhd sayğacı (Retry Limit)

Ən sadə və ən etibarlı üsul — resursun ələ keçirilməsi cəhdlərinin sayını məhdudlaşdırmaqdır. Əgər N cəhddən sonra əməliyyat uğursuz olarsa, ip xəta vəziyyətinə keçir və istifadəçini xəbərdar edir. N empirik olaraq seçilir: mobil tətbiqlər üçün adətən 3-5 cəhd. Bu, yüksək yük altında nadir yanlış işə düşmələr bahasına sonsuz Livelock-u tamamilə aradan qaldırır.

Jitter ilə Exponential Backoff

Cəhdlər arasında sabit gecikmə əvəzinə eksponensial artan fasilə istifadə olunur. Formula: delay = min(baseDelay * 2^attempt, maxDelay) + random(0, jitter). Bu yanaşma təkcə iplərin sinxronluğunu pozmur, həm də yüksək rəqabət zamanı ümumi sistem yükünü azaldır. Şəbəkə protokollarının alqoritmlərində istifadə olunur və Google tərəfindən Firebase Realtime Database retry məntiqi üçün tövsiyə edilir.

Prioritet və asimmetrik məntiq

Müxtəlif iplərə fərqli strategiyalar təyin etmək Livelock-un səbəbini — münaqişəyə eyni reaksiyanı — aradan qaldırır. Məsələn, yüksək prioritetli ip resursu boşaltmadan alır, aşağı prioritetli isə boşaldır və gözləyir. Mobil inkişafda UI ipi bloklamaların ələ keçirilməsində prioritetə malik ola bilər, fon işçi ipləri isə timeout ilə TryLock istifadə edə bilər.

Tsiklik boşaltmadan imtina

Bəzi arxitekturalarda Livelock dizayn səviyyəsində qarşısı alınır: resursların yalnız bir istiqamətdə boşaldılması. Məsələn, İp A həmişə nəzarəti İp B-yə sabit kanal (Channel) vasitəsilə ötürürsə və B heç vaxt nəzarəti A-ya qaytarmağa çalışmırsa — reaksiya dövrü mümkün deyil. Android CameraX və MediaPipe-də tək istiqamətli emal mərhələləri olan boru kəməri arxitekturası qonşu mərhələlər arasında Livelock-u tamamilə aradan qaldırır.

Tez-tez verilən suallar

Livelock-u sonsuz döngüdən necə ayırd etmək olar?

Sonsuz döngü xarici amillərdən asılı deyil və digər iplərlə qarşılıqlı əlaqə olmadan bir əməliyyatı təkrarlayır. Livelock — bu həmişə digər iplərin hərəkətlərinə reaksiyadır: ip qonşu iplərin vəziyyətinə cavab olaraq davranışını dəyişir, qapalı əks əlaqə yaradır. Livelock zamanı Thread Dump daimi kontekst dəyişməsini göstərir.

Verilənlər bazası kontekstində Livelock nədir?

Verilənlər bazalarında Livelock, tranzaksiyanın daim təxirə salınması səbəbindən yaranır. Məsələn, DBMS wait-die alqoritmindən istifadə edir: başlama vaxtı daha kiçik olan tranzaksiya daha yenisi ilə toqquşarsa, geri qaytarılır və yenidən başladılır, lakin hər dəfə eyni toqquşmaya düşür. Bu, randomized restart delay ilə həll olunur.

Livelock nə vaxt faydalıdır?

Bəzi sistemlərdə Livelock Deadlock-dan daha üstün hesab olunur, çünki iplər aktiv qalır və problemi aşkarlaya bilir. Məsələn, optimist bloklama (optimistic locking) alqoritmlərində livelock-a bənzər davranışa icazə verilir, əgər retry limit sonlu tamamlanmanı təmin edirsə. Bu, performans və irəliləyiş təminatı arasında kompromisdir.

Livelock test etməyə necə təsir edir?

Livelock testlərdə çox çətin təkrarlanır, çünki iplərin vaxtlarının dəqiq üst-üstə düşməsini tələb edir. Vahid testlər deterministik şəkildə icra olunur və nadir hallarda aktiv bloklamanı aşkarlayır. Yük altında çoxsaylı işə salmalarla Stress Testing və profilerdə CPU istehlakının monitorinqi tövsiyə olunur.

Android-də Livelock serverdəki Livelock-dan nə ilə fərqlənir?

Serverdə Livelock performans deqradasiyasına və timeout-lara gətirib çıxarır, lakin server üfüqi miqyaslanır. Android-də Livelock batareyanı boşaldır və cihazı qızdırır, daha pis UX yaradır. Bundan əlavə, mobil cihazlarda CPU nüvələrinin sayı məhduddur, buna görə Livelock daha tez bütün sistemin işlək vəziyyətini itirməsinə səbəb olur.

Nəticə

  • Livelock — iplərin bloklanmadığı, lakin irəliləyiş olmadan münaqişələrə sonsuz reaksiya verdiyi aktiv bloklama vəziyyəti
  • Deadlock-dan fərqli olaraq, Livelock zamanı iplər 100% CPU sərf edir ki, bu da mobil cihazlar üçün kritikdir
  • Əsas səbəb — münaqişəyə eyni reaksiya strategiyası və gecikmələrdə təsadüfiliyin olmaması
  • Jitter ilə Exponential backoff sinxron dövrləri pozur və aktiv bloklamanın qarşısını alır
  • Retry limit (3-5 cəhd) sonsuz Livelock-u tamamilə aradan qaldırır
  • CPU Profiler Android Studio-da və Battery Historian — Livelock diaqnostikasının əsas alətləri
  • Asimmetrik məntiq müxtəlif iplər üçün resursların ələ keçirilməsi aktiv bloklama ehtimalını aradan qaldırır

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun