Middle+
Korutinalarla işləyərkən sinxronizasiya blokları və oxşar quruluşların istifadəsi tövsiyə edilmir?
sobes.tech Süni İntellekt
AI-dan cavab
Korutinalar ilə işləyərkən synchronized və ya standart kitabxanadan lock kimi bloklayıcı quruluşların istifadəsi resursların səmərəli istifadə edilməməsinə və problemlərə səbəb ola bilər.
Əsas səbəblər:
- İş parçacığının bloklanması: Sinxronizasiya blokları, yalnız korutinləri deyil, həm də iş parçacığını dayandırır. Əgər sinxronlaşdırılmış blok daxilində Suspending funksiyası icra olunursa, iş parçacığı Suspending funksiyası tamamlanana və kilid azad olunana qədər bloklanır. Bu, digər korutinlərin eyni iş parçacığını istifadə etməsinə mane olur və "açlıq" yaradır.
- Suspending funksiyalarla uyğun deyil: Korutinlərin işləmə mexanizmi (kontekst dəyişimi, davamlar) iş parçacığı səviyyəsindəki bloklamaları nəzərə almır. Suspending funksiyasını sinxronlaşdırılmış blok daxilində icra etmək, korutinlərin bloklamayan təbiətinə ziddir.
- Strukturlaşdırılmış rəqabət prinsiplərinin pozulması: Korutinlər özlərinin ləğv işarələri və hierarxiyası var. İş parçacığı səviyyəsindəki bloklar bu sistemi nəzərə almır, düzgün ləğv və həyat dövrü idarəetməsini çətinləşdirir.
- Deadlock riski: İş parçacığı blokları və korutinlərin rəqabət mexanizmlərinin birləşməsi, mürəkkəb deadlockların yaranma ehtimalını artırır və onları ayıklamağı çətinləşdirir.
İş parçacığı səviyyəsindəki bloklar yerinə, kotlinx.coroutines kitabxanasından xüsusi rəqabət primitivalarından istifadə etmək tövsiyə olunur:
Mutex: qarşılıqlı istisna təmin edir. Zabit olunmuş mutex-i almağa çalışan korutin suspends (iş parçacığını bloklamadan) və mutex azad olunana qədər gözləyir.Semaphore: eyni zamanda resursa giriş sayını məhdudlaşdırır.Channel: korutinlər arasında məlumat mübadiləsi üçün istifadə olunur.Atomik dəyişənlər: sadə atomik əməliyyatlar üçün.
Mutex istifadəsinin nümunəsi:
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.*
val mutex = Mutex()
var counter = 0
suspend fun incrementCounter() {
mutex.withLock {
// Kritik bölmə
counter++
}
}
fun main() = runBlocking {
// Eyni zamanda giriş üçün çox sayda korutin yaradılır
repeat(1000) {
launch {
incrementCounter()
}
}
delay(1000) // Korutinlərin işləməsi üçün vaxt verilir
println("Counter: $counter") // 1000 gözlənilir
}
mutex.withLock suspending-funksiyadır. Əgər mutex məşğuldursa, withLock-u çağıran korutin dayandırılır və thread digər tapşırıqlar üçün sərbəst buraxılır. Mutex əlçatan olduqda, korutin davam edir. Bu, synchronized-dən fərqli olaraq, thread-i bloklamır.