JavaRush /Kurslar /All lectures for UZ purposes /Nitlarda mustaqillik yo'q! synchronized kerak!

Nitlarda mustaqillik yo'q! synchronized kerak!

All lectures for UZ purposes
Daraja, Dars
Mavjud

— Salom, Amigo! Bizda davo bor – barcha kasalliklardan davo. Biz allaqachon aniq bir narsani tushundik – nitlarning nazoratsiz o'zgarishi bu muammo.

— Nega nitlar o'zlari, qachon o'zgarishini hal qilmaydi? Hammasi muhim ishlar qilinganida "men tayyorman" deb signal beradi.

— Nitlarga o'z-o'zini boshqarishni ruxsat berish - bu yanada katta muammo. Agar biror kod yaxshi yozilmagan bo'lsa, narsa hech qachon o'z "processor vaqtini" bermas. Uzoq vaqt avval shunday edi - va bu tinch dahshat edi.

— Xo'sh. Qanday yechim bor?

—Nitlar blokirovkasi. Va bu qanday ishlaydi.

Aniqlandi ki, nitlar bir-biridan bezovta qiladi, qachonki ular umumiy ob'ektlar yoki resurslar bilan birgalikda ishlashga harakat qilsa. Konsolga chiqish misolida: konsol bitta, lekin barcha nitlar unga chiqadi. Bu tartibsizlik.

Shuning uchun maxsus ob'ekt - mutex ixtiro qilindi. Bu xuddi hojatxona eshigidagi "bo'sh" "band" belgisiga o'xshaydi. U ikki holatda bo'ladi - ob'ekt bo'sh va ob'ekt band, yoki ularni ham bloklangan va blokdan chiqarilgan deb atashadi.

Qachonki biror nitga barcha nitlar uchun umumiy ob'ekt kerak bo'lsa, u shu ob'ekt bilan bog'liq mutexni tekshiradi. Agar mutex bo'sh bo'lsa, nit uni bloklaydi (band deb belgilaydi) va umumiy resursdan foydalanishni boshlaydi. U ishlarini tugatgandan so'ng, mutex blokdan chiqariladi (bo'sh deb belgilaydi).

Agar nit ob'ektdan foydalanmoqchi bo'lsa, lekin mutex band bo'lsa, unda nit kutadi. Qachonki mutex band nit tomonidan bo'shatilsa, bizning nit uni darhol bloklaydi va ishga kirishadi. Hojatxona belgilari bilan to'liq o'xshashlik.

— Qanday qilib bu mutex bilan ishlash mumkin. Maxsus ob'ektlar yaratish kerakmi?

— Hammasi juda oson. Java ishlab chiquvchilari bu mutexni Object klassiga qo'shishgan. Senga uni yaratish ham kerak emas bo'ladi. U har bir ob'ektda mavjud. Mana qanday ishlaydi:

Kod Tavsif
class MyClass
{
private String name1 = "Olya";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Method swap o'zgaruvchilar name1 & name2 qiymatlarini almashtiradi.

Uni ikki taddan bir vaqtda chaqirsak nima bo'ladi?

Yakuniy tartib Birinchi nit kodi Ikkinchi nit kodi
String s1 = name1; //Olya
name1 = name2; //Lena
name2 = s1; //Olya

String s2 = name1; //Lena
name1 = name2; //Olya
name2 = s2; //Lena
String s1 = name1; name1 = name2;
name2 = s1;
//boshqa nit ishlamoqda
//boshqa nit ishlamoqda
//boshqa nit ishlamoqda
//nit kutmoqda, mutex bo'shatilishini kutmoqda
//nit kutmoqda, mutex bo'shatilishini kutmoqda
//nit kutmoqda, mutex bo'shatilishini kutmoqda
String s2 = name1; name1 = name2;
name2 = s2;
Yakun
O'zgaruvchilar qiymatlari ikki marta almashtirildi va boshlang'ich holatga qaytdi.

Kalit so'zga e'tibor bering synchronized.

— Ha, bu nimani anglatadi?

— Qachonki bir nit synchronized bilan belgilangan kod blokiga kirsa, Java-mashina darhol synchronized so'zi keyingi dumaloq qavs ichida ko'rsatilgan ob'ektning mutexini bloklaydi. Boshqa hech bir nit bu blokga kira olmaydi, to bizning nit bu blokni tark etmaguncha. Bizning nit synchronized bilan belgilangan blokdan chiqishi bilan, mutex avtomatik tarzda blokdan chiqariladi va boshqa nit tomonidan qo'lga kiritilishi uchun bo'shatiladi.

Agar mutex band bo'lsa, bizning nit joyida turgan bo'ladi va u bo'shatilishini kutadi.

— Juda oson va naqadar chiroyli. Chiroyli yechim.

— Ha. Qanday deb o'ylaysiz, bu holatda nima bo'ladi?

Kod Tavsif
class MyClass
{
private String name1 = "Olya";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public void swap2()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Methodlar swap va swap2 bitta mutexga ega – ob'ekt this.

Agar bir nit swap metodini chaqirsa va boshqa nit swap2 metodini chaqirsa nima bo'ladi?

— Ularning mutexlari bitta, shuning uchun birinchi nit synchronized blokidan chiqmayincha, ikkinchi nit kutishga majbur bo'ladi, shuning uchun bu erda bir vaqtda kirishda muammo bo'lmaydi.

— Zo'r, Amigo! To'g'ri yechim!

Tahminlaringizni quyidagi muhim jihatlarga qaratmoqchiman, synchronized kalit so'zi bilan nafaqat kod qismini, balki metodni ham belgilash mumkin. Bu nimani bildiradi:

Kod Haqiqatda nima sodir bo'ladi
class MyClass
{
private static String name1 = "Olya";
private static String name2 = "Lena";

public synchronized void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}

public static synchronized void swap2()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
class MyClass
{
private static String name1 = "Olya";
private static String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public static void swap2()
{
synchronized (MyClass.class)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION