Synchronized Java tilidagi o'rnatilgan sinxronizatsiya mexanizmi bo'lib, kodning muhim qismlariga eksklyuziv kirishni ta'minlaydi. Oracle, 2024 ma'lumotlariga ko'ra, synchronized modifikatori faqat bitta oqim belgilangan metod yoki blokni ma'lum bir vaqtda bajarishini kafolatlaydi. Bu mexanizm monitorlarga — operatsion tizimlarning fundamental kontseptsiyasiga asoslanadi va barcha murakkablik darajalarida ko'p oqimli ilovalarning to'g'ri ishlashini ta'minlaydi.
Asosiy ma'lumotlar
Synchronized Java-da kalit so'z bo'lib, faqat bitta oqim bir vaqtning o'zida himoyalangan kod qismini bajarishini kafolatlaydi, parallel kirishda ma'lumotlarning buzilishini oldini oladi. U Java-ning birinchi versiyasida paydo bo'lgan va har qanday darajadagi dasturchilar uchun oqim xavfsizligini ta'minlashning eng oddiy usuli bo'lib qolmoqda.
Synchronized modifikatori ikkita vazifani hal qiladi: o'zaro istisno (mutual exclusion) va o'zgarishlarning ko'rinishi (visibility). Bir oqim synchronized blokidan chiqqanda, barcha o'zgarishlar xuddi shu obyektda sinxronlashtirilgan blokga kiradigan boshqa oqimlarga ko'rinadigan bo'ladi.
Synchronized butun metodga yoki ixtiyoriy kod blokiga monitor-obyekt ko'rsatilgan holda qo'llanilishi mumkin. Ikkala holatda ham JVM bayt-kod darajasida monitorenter va monitorexit ko'rsatmalarini joylashtiradi.
Sinxronizatsiyasiz ko'p oqimli ilovalarda poyga holati (race condition) yuzaga keladi — ikki oqim bir vaqtda bir xil ma'lumotlarni o'zgartirganda kutilmagan natijalarga olib keladi. Synchronized ushbu muammoga qarshi kurashish uchun Java-ning birinchi va asosiy vositasi bo'lib, har bir dasturchi uchun mavjud bo'lgan oddiy deklarativ sintaksisni taqdim etdi.
Synchronized mexanizmi monitor kontseptsiyasiga asoslanadi — har bir Java obyektiga o'rnatilgan yuqori darajadagi sinxronizatsiya primitivi. Monitor obyekt bilan birinchi synchronized blokidan foydalanilganda bog'lanadi.
Java-dagi har bir obyekt bog'langan monitorga ega. Bir oqim synchronized blokiga kirganda, u obyekt monitorini egallaydi. Agar monitor allaqachon boshqa oqim tomonidan band bo'lsa, oqim bo'shatilgunga qadar bloklanadi. Bayt-kodda bunga monitorenter va monitorexit ko'rsatmalari juftligi mos keladi.
JVM synchronized-ni bir necha darajalar orqali optimallashtiradi: yagona oqimli kirish uchun biased locking (yo'naltirilgan bloklash), past raqobatda lightweight locking (engil bloklash) va intensiv raqobatda OS ishtirokida heavyweight locking (og'ir bloklash). Bu darajalar kodni o'zgartirmasdan ishlashni yaxshilaydi.
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
Synchronized happens-before munosabatini o'rnatadi: synchronized blokidan chiqishdan oldin oqimdagi barcha harakatlar xuddi shu obyektda sinxronlashtirilgan blokga kirganidan keyin boshqa oqimga ko'rinadi. Bu nafaqat o'zaro istisnoni, balki barcha oqimlar uchun ma'lumotlarning izchilligini ham kafolatlaydi.
Java synchronized qo'llashning ikki usulini taklif qiladi: metod darajasida va blok darajasida. Tanlov ular orasida ishlash va sinxronizatsiya granularligiga ta'sir qiladi.
Metodni synchronized modifikatori bilan belgilab, uni avtomatik ravishda joriy misolda (oddiy metod uchun) yoki Class obyektida (statik metod uchun) sinxronlashtirasiz. Bu o'zaro istisnoni ta'minlashning eng oddiy usuli, ammo muhim qism metodning faqat kichik bir qismini tashkil qilsa va qolgan kod sinxronizatsiyani talab qilmasa, ko'pincha ortiqcha.
Synchronized blok aniq nazorat beradi: siz monitor-obyektni belgilaysiz va kodning faqat kerakli qismini sinxronlashtirasiz, metodning qolgan qismini bloklashdan tashqarida qoldirasiz. Bu monitorni ushlab turish vaqtini minimallashtiradi va ko'p oqimli muhitda ilovaning umumiy ishlashini oshiradi, chunki boshqa oqimlar monitorning bo'shatilishini kutmasdan parallel ravishda bog'liq bo'lmagan kodni bajarishi mumkin.
class DataProcessor {
private final Object lock = new Object();
public void process() {
// kritik bo'limdan tashqari kod - sinxronizatsiyasiz
prepareData()
synchronized (lock) {
// faqat shu blok himoyalangan
updateSharedState()
}
// bloklamasdan davom
cleanup()
}
}
| Mezon | Synchronized metod | Synchronized blok |
|---|---|---|
| Monitor | this (misol) yoki Class | istalgan obyekt |
| Granularlik | butun metod | faqat kerakli kod |
| O'qish qulayligi | yuqori | o'rta |
| Ishlash | katta metodda past | kichik muhim qismda yuqori |
Android dasturlashda synchronized SharedPreferences, ma'lumotlar bazasiga kirish va UI komponentlarini himoya qilish uchun keng qo'llaniladi. Biroq, uni asosiy oqimda ishlatish interfeysning muzlashi xavfi tufayli qat'iyan tavsiya etilmaydi.
Android'dagi SharedPreferences asosiy oqim xavfsizligini ta'minlaydi, ammo bir nechta oqimlar tomonidan Editor orqali tahrirlashda tashqi sinxronizatsiya talab qilinishi mumkin. Alohida bloklash obyekti bilan synchronized blok o'zgarishlarning izchilligini kafolatlaydi.
class PreferencesManager(private val prefs: SharedPreferences) {
private val lock = Any()
fun writeToken(token: String) {
synchronized (lock) {
prefs.edit()
.putString("auth_token", token)
.apply()
}
}
}
Android'da synchronized-ning asosiy cheklovi — oqimni bloklash. Mutex bilan koroutinlardan farqli o'laroq, synchronized butun tizim oqimini bloklaydi. Asosiy oqimda bu ANRga sabab bo'ladi. Zamonaviy Android dasturlashda synchronized-ni koroutinlar (suspend Mutex) yoki atomik turlar (AtomicInteger) bilan almashtirish tavsiya etiladi.
Zamonaviy Java va Kotlin synchronized-ga bir nechta alternativlarni taklif qiladi, ularning har biri bir xil vazifalarni kamroq cheklovlar yoki yaxshiroq ishlash bilan hal qiladi.
Lock interfeysi ReentrantLock va ReadWriteLock implementatsiyalari bilan vaqt chegarasi, uzilishi mumkin bo'lgan kutish va bir nechta Condition navbatlarini taqdim etadi. U synchronized-dan moslashuvchanroq, ammo finally-da aniq bo'shatishni talab qiladi, bu unutilgan unlock tufayli xato xavfini oshiradi.
AtomicInteger, AtomicLong, AtomicReference va boshqa sinflar CAS (Compare-And-Swap) asosidagi Lock-Free algoritmlaridan foydalanadi. Ular o'rtacha raqobat stsenariylarida synchronized-dan sezilarli darajada tezroq, chunki oqimlarni bloklamaydi, optimistik takroriy urinishlarni bajaradi va OS yadrosi tomonidan kontekst almashtirishni talab qilmaydi.
ThreadLocal muqobil yondashuvni taqdim etadi: har bir ThreadLocal o'zgaruvchisi bitta oqim doirasida izolyatsiya qilingan va o'qish/yozish uchun sinxronizatsiyani talab qilmaydi. Bu oqimlar o'rtasida ulashilmasligi kerak bo'lgan ma'lumotlar uchun synchronized ehtiyojini butunlay bartaraf qiladi. ThreadLocal freymvorklarda (Spring, Hibernate) tranzaksiya konteksti va sessiyalarni saqlash uchun faol qo'llaniladi.
Android uchun Kotlin loyihalarida synchronized alternativi kotlinx.coroutines dan Mutex dir. U operatsion tizim oqimini bloklamaydi, balki bloklash bo'shatilgunga qadar koroutinni to'xtatadi — bu hovuz oqimlaridan samarali foydalanish va resursning bo'shatilishini uzoq kutishda ANRdan qochish imkonini beradi.
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
val mutex = Mutex()
var counter = 0
suspend fun safeIncrement() {
mutex.withLock {
counter++
}
}
Synchronized ishlashi Java-ning so'nggi versiyalarida sezilarli darajada o'zgargan. Ilgari uni "og'ir" mexanizm deb hisoblashgan, ammo zamonaviy JVMlar JIT-kompilyatorning ilg'or optimallashuvlari tufayli qo'shimcha yuklarning ko'pini bartaraf qilgan. Virtual mashinaning sinxronlashtirilgan kodni ish vaqtida qanday tezlashtirishini batafsil ko'rib chiqaylik.
JVM JIT-kompilyatori bir nechta optimallashuvlarni qo'llaydi: biased locking bloklashni har doim bitta oqim egallasa, sinxronizatsiyani bartaraf qiladi; lock coarsening qo'shni synchronized bloklarini bittaga birlashtiradi; lock elimination obyekt faqat bitta oqim uchun mavjud bo'lsa, sinxronizatsiyani olib tashlaydi. Bu optimallashuvlar past raqobatda synchronized-ni amalda bepul qiladi.
JVM har bir obyekt uchun raqobat darajasini aniqlaydi: raqobat bo'lmaganda biased locking yoqiladi, ikkinchi oqim paydo bo'lganda bloklash spin-kutish bilan lightweight rejimiga o'tadi va faqat uzoq kutishda — tizim muteksi bilan heavyweight-ga o'tadi. Bu eskalatsiya avtomatik ravishda sodir bo'ladi va dasturchi qo'lda strategiya tanlashi shart emas.
Zamonaviy benchmarklarda (Java 17+) synchronized past va o'rtacha raqobatda ReentrantLock bilan solishtirish mumkin bo'lgan ishlashni ko'rsatadi. Yuqori raqobatda Lock, timeout va uzilish qo'llab-quvvatlashi bilan samaraliroq kutish navbati tufayli ustunlikka ega bo'lishi mumkin. Raqobat doimiy bo'lgan yuqori yuklangan tizimlar uchun fair rejimidagi ReentrantLock oldindan bashorat qilinadigan xatti-harakatni beradi.
Atomik sinflar (AtomicInteger, AtomicReference) oddiy hisoblagichlar va bayroqlar uchun CAS asosidagi Lock-Free implementatsiyasi tufayli eng tez bo'lib qolmoqda. Ular oqimlarni umuman bloklamaydi — ziddiyatda operatsiya shunchaki siklda takrorlanadi. Bu 4-8 oqimda hisoblagichni oshirish operatsiyalarida synchronized bilan solishtirganda 3-5 marta ishlash o'sishini beradi.
Tez-tez beriladigan savollar
Synchronized ham o'zaro istisnoni, ham ko'rinishni ta'minlaydi. Volatile faqat o'zgarishlarning ko'rinishini kafolatlaydi — volatile o'zgaruvchisiga yozish barcha oqimlarga ko'rinadi, lekin bir vaqtda o'zgartirishning oldini olmaydi, ya'ni poyga holatidan himoya qilmaydi.
Ha, deadlock turli monitor tartibi bilan ichma-ich sinxronizatsiyada mumkin. Masalan, bir oqim synchronized(a) { synchronized(b) }, ikkinchisi synchronized(b) { synchronized(a) } chaqiradi. Ichma-ich synchronized bloklaridan qoching yoki yagona monitor tartibini belgilang.
Monitor — har bir Java obyekti bilan bog'liq sinxronizatsiya mexanizmi. U faqat bitta oqimning berilgan obyektda synchronized kodini bajarishini kafolatlaydi. Monitor bloklash, kutish navbati va wait/notify orqali xabardor qilishni kutayotgan oqimlar hovuzini o'z ichiga oladi.
Java-ning zamonaviy versiyalarida (17+) synchronized JIT optimallashuvlari (biased locking, lock coarsening) tufayli Lock-dan ishlash jihatidan qolishmaydi. Lock tezlik uchun emas, balki qo'shimcha imkoniyatlar uchun afzal: vaqt chegarasi, uzilishi mumkin bo'lgan kutish va bir nechta Condition.
Statik synchronized metod sinfning misoli emas, balki shu sinfning Class obyekti monitoridan foydalanadi. Bu sinxronizatsiya sinfning barcha misollarini qamrab olishini anglatadi. Statik bo'lmagan va statik synchronized metodlari turli monitorlardan foydalanadi va bir-birini bloklamaydi.
Xulosa
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.