JavaRush /Java blogi /Random-UZ /26-daraja. Daraja mavzusi bo'yicha suhbat savollariga jav...
zor07
Daraja
Санкт-Петербург

26-daraja. Daraja mavzusi bo'yicha suhbat savollariga javoblar. 2-qism. 6-9, 11-12 savollar

Guruhda nashr etilgan
26-daraja. Daraja mavzusi bo'yicha suhbat savollariga javoblar.  2-qism. 6-9, 11-12-savollar - 1

6. Kankarenzi nima?

Concurrency - bu Java-dagi sinf kutubxonasi bo'lib, u bir nechta mavzularda ishlash uchun optimallashtirilgan maxsus sinflarni o'z ichiga oladi. Ushbu sinflar paketga yig'iladi java.util.concurrent. Funksionalligiga ko‘ra ularni sxematik tarzda quyidagicha ajratish mumkin: 26-daraja. Daraja mavzusi bo'yicha suhbat savollariga javoblar.  2-qism. 6-9, 11-12 - 2-savollarConcurrent Collectionsjava.util – to‘plamdagi standart universal to‘plamlarga qaraganda ko‘p tarmoqli muhitda samaraliroq ishlaydigan to‘plamlar to‘plami . Butun to'plamga kirishni bloklaydigan asosiy o'ram o'rniga Collections.synchronizedListma'lumotlar segmentlarida qulflar qo'llaniladi yoki kutishsiz algoritmlar yordamida ma'lumotlarni parallel o'qish uchun ish optimallashtiriladi. Navbatlar - ko'p tarmoqli qo'llab-quvvatlanadigan bloklanmaydigan va blokirovka qiluvchi navbatlar. Bloklanmagan navbatlar iplarni blokirovka qilmasdan tezlik va ishlash uchun mo'ljallangan. Bloklash navbatlari, agar ba'zi shartlar bajarilmasa, masalan, navbat bo'sh yoki to'lib ketgan bo'lsa yoki bepul "Iste'molchi" bo'lmasa, "Ishlab chiqaruvchi" yoki "Iste'molchi" iplarini "sekinlashtirish" kerak bo'lganda qo'llaniladi. Sinxronizatorlar iplarni sinxronlashtirish uchun yordamchi yordamchi dasturlardir. Ular "parallel" hisoblashda kuchli quroldir. Ijrochilar - ip hovuzlarini yaratish, asinxron vazifalarni rejalashtirish va natijalarni olish uchun ajoyib ramkalarni o'z ichiga oladi. Qulflar - asosiy synchronizedbo'lganlarga nisbatan muqobil va yanada moslashuvchan ip sinxronlash mexanizmlarini ifodalaydi . Atomika - ibtidoiy va havolalar ustida atom operatsiyalarini qo'llab-quvvatlaydigan sinflar. Manba:waitnotifynotifyAll

7. Kankarensidan qanday sinflarni bilasiz?

Bu savolga javob ushbu maqolada to'liq bayon etilgan . Bu erda hammasini qayta nashr etishdan ma'no ko'rmayapman, shuning uchun men qisqacha tanishish sharafiga muyassar bo'lgan sinflarning tavsifini beraman. ConcurrentHashMap<K, V> - Hashtableva bloklaridan synhronizedfarqli o'laroq HashMap, ma'lumotlar kalitlar xeshlariga bo'lingan segmentlar shaklida taqdim etiladi. Natijada, ma'lumotlarga bitta ob'ekt emas, balki segmentlar orqali kirish mumkin. Bundan tashqari, iteratorlar ma'lum bir vaqt oralig'idagi ma'lumotlarni ifodalaydi va tashlamaydi ConcurrentModificationException. AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray - Agar sinfda bitta oddiy o'zgaruvchiga kirishni sinxronlashtirish kerak bo'lsa-chi int? Siz bilan konstruksiyalardan foydalanishingiz mumkin synchronizedva atom operatsiyalaridan foydalanganda set/get, volatile. Lekin siz yangi sinflardan foydalangan holda yanada yaxshi ish qilishingiz mumkin Atomic*. CAS-dan foydalanish tufayli, ushbu sinflar bilan operatsiyalar orqali sinxronlashtirilgandan ko'ra tezroq synchronized/volatile. Bundan tashqari, ma'lum miqdorda atom qo'shish, shuningdek oshirish/kamaytirish usullari mavjud.

8. ConcurrentHashMap klassi qanday ishlaydi?

Uni joriy qilish vaqtida ConcurrentHashMapJava dasturchilariga quyidagi xesh-xaritani amalga oshirish kerak edi:
  • Ip xavfsizligi
  • Unga kirishda butun stolda hech qanday qulf yo'q
  • O'qish operatsiyasini bajarishda stol qulflari bo'lmasligi ma'qul
Amalga oshirishning asosiy g'oyalari ConcurrentHashMapquyidagilardan iborat:
  1. Xarita elementlari

    Elementlardan farqli o'laroq HashMap, Entryin ConcurrentHashMapsifatida e'lon qilinadi volatile. Bu JMM dagi o'zgarishlar tufayli ham muhim xususiyatdir .

    static final class HashEntry<K, V> {
        final K key;
        final int hash;
        volatile V value;
        final HashEntry<K, V> next;
    
        HashEntry(K key, int hash, HashEntry<K, V> next, V value) {
            this .key = key;
            this .hash = hash;
            this .next = next;
            this .value = value;
         }
    
        @SuppressWarnings("unchecked")
        static final <K, V> HashEntry<K, V>[] newArray(int i) {
            return new HashEntry[i];
        }
    }
  2. Xesh funktsiyasi

    ConcurrentHashMaptakomillashtirilgan xeshlash funksiyasidan ham foydalaniladi.

    HashMapJDK 1.2 da qanday bo'lganini eslatib o'taman :

    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

    ConcurrentHashMap JDK 1.5 versiyasi:

    private static int hash(int h) {
        h += (h << 15) ^ 0xffffcd7d;
        h ^= (h >>> 10);
        h += (h << 3);
        h ^= (h >>> 6);
        h += (h << 2) + (h << 14);
        return h ^ (h >>> 16);
    }

    Nega hash funktsiyasini murakkabroq qilish kerak? Xesh xaritasidagi jadvallar uzunligi ikki kuch bilan belgilanadi. Ikkilik ko'rinishlari past va yuqori holatda farq qilmaydigan xesh kodlari uchun bizda to'qnashuvlar bo'ladi. Xash funktsiyasining murakkabligini oshirish bu muammoni hal qiladi va xaritadagi to'qnashuvlar ehtimolini kamaytiradi.

  3. Segmentlar

    Xarita N xil segmentga bo'lingan (sukut bo'yicha 16 ta, maksimal qiymat 16 bit bo'lishi mumkin va ikkita quvvat). Har bir segment xarita elementlarining ip-xavfsiz jadvalidir. Segmentlar sonini ko'paytirish bir nechta segmentlarni qamrab olish uchun o'zgartirish operatsiyalarini rag'batlantiradi va ish vaqtida blokirovka qilish ehtimolini kamaytiradi.

  4. ConcurrencyLevel

    Ushbu parametr xotira kartasidan foydalanish va kartadagi segmentlar soniga ta'sir qiladi.

    Segmentlar soni concurrencyLevel dan kattaroq ikkining eng yaqin kuchi sifatida tanlanadi. ConcurrencyLevel darajasini pasaytirish, yozish paytida mavzular xarita segmentlarini bloklash ehtimolini oshiradi. Ko'rsatkichni ortiqcha baholash xotiradan samarasiz foydalanishga olib keladi. Agar faqat bitta ip xaritani o'zgartirsa va qolganlari o'qisa, 1 qiymatidan foydalanish tavsiya etiladi.

  5. Jami

    Shunday qilib, asosiy afzalliklari va amalga oshirish xususiyatlari ConcurrentHashMap:

    • Xaritada shunga o'xshash hashmapo'zaro ta'sir interfeysi mavjud
    • O'qish operatsiyalari qulflarni talab qilmaydi va parallel ravishda amalga oshiriladi
    • Yozish operatsiyalari ko'pincha blokirovkasiz parallel ravishda ham amalga oshirilishi mumkin
    • Yaratishda kerakli ko'rsatiladi concurrencyLevel, o'qish va yozish statistikasi bilan aniqlanadi
    • valueXarita elementlari deb e'lon qilingan qiymatga egavolatile
    Manba: ConcurrentHashMap qanday ishlaydi

9. Lock sinfi nima?

Umumiy manbaga kirishni nazorat qilish uchun biz sinxronlashtirilgan operatorga muqobil qulflardan foydalanishimiz mumkin. Qulflash funksiyasi ichida paketlangan java.util.concurrent.locks. Birinchidan, mavzu umumiy manbaga kirishga harakat qiladi. Agar u bepul bo'lsa, u holda ipga qulf o'rnatiladi. Ish tugagandan so'ng, umumiy resursdagi qulf chiqariladi. Agar resurs bo'sh bo'lmasa va unga allaqachon qulf o'rnatilgan bo'lsa, ip bu qulf bo'shatilguncha kutadi. LockQulflash sinflari quyidagi usullarni belgilaydigan interfeysni amalga oshiradi :
  • void lock():qulf olinmaguncha kutadi
  • boolean tryLock():qulf olishga harakat qiladi; agar qulf olinsa, u true ni qaytaradi . Agar qulf olinmasa, u false ni qaytaradi . Usuldan farqli o'laroq, lock()agar mavjud bo'lmasa, u qulfni olishni kutmaydi
  • void unlock():qulfni olib tashlaydi
  • Condition newCondition():Conditionjoriy qulf bilan bog'langan ob'ektni qaytaradi
Umumiy holatda qulflashni tashkil etish juda oddiy: qulfni olish uchun usul chaqiriladi va umumiy resurslar bilan ishlashni tugatgandan so'ng, qulfni chiqaradigan lock()usul chaqiriladi . unlock()Ob'ekt Conditionsizga blokirovka qilishni boshqarish imkonini beradi. Qoida tariqasida qulflar bilan ishlash uchun ReentrantLockpaketdagi sinfdan foydalaniladi.Ushbu java.util.concurrent.locks.sinf interfeysni amalga oshiradi Lock. Misol tariqasida kichik dastur yordamida Java Lock API-dan foydalanishni ko'rib chiqaylik: Aytaylik, bizda Resourceip xavfsizligi talab qilinmaydigan bir nechta ip-xavfsiz usullar va usullardan iborat sinf mavjud.
public class Resource {

    public void doSomething(){
        // пусть здесь происходит работа с базой данных
    }

    public void doLogging(){
        // потокобезопасность для логгирования нам не требуется
    }
}
RunnableEndi interfeysni amalga oshiradigan va sinf usullaridan foydalanadigan sinfni olaylik Resource.
public class SynchronizedLockExample implements Runnable{

    // экземпляр класса Resource для работы с методами
    private Resource resource;

    public SynchronizedLockExample(Resource r){
        this.resource = r;
    }

    @Override
    public void run() {
        synchronized (resource) {
            resource.doSomething();
        }
        resource.doLogging();
    }
}
Endi yuqoridagi dasturni o'rniga Lock API yordamida qayta yozamiz synchronized.
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// класс для работы с Lock API. Переписан с приведенной выше программы,
// но уже без использования ключевого слова synchronized
public class ConcurrencyLockExample implements Runnable{

    private Resource resource;
    private Lock lock;

    public ConcurrencyLockExample(Resource r){
        this.resource = r;
        this.lock = new ReentrantLock();
    }

    @Override
    public void run() {
        try {
            // лочим на 10 секунд
            if(lock.tryLock(10, TimeUnit.SECONDS)){
            resource.doSomething();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //убираем лок
            lock.unlock();
        }
        // Для логгирования не требуется потокобезопасность
        resource.doLogging();
    }

}
Dasturdan ko'rinib turibdiki, biz tryLock()ipning faqat ma'lum bir vaqtni kutishiga ishonch hosil qilish uchun usuldan foydalanamiz. Agar u ob'ektda qulfni olmagan bo'lsa, u shunchaki jurnalga kiradi va chiqadi. Yana bir muhim nuqta. Agar usul istisno bo'lsa try-finallyham, qulf bo'shatilishini ta'minlash uchun siz blokdan foydalanishingiz kerak . Manbalar:doSomething()

11. Muteks nima?

Muteks - bu mavzularni/jarayonlarni sinxronlashtirish uchun maxsus ob'ekt. Bu ikki holatni olishi mumkin - band va bepul. Soddalashtirish uchun mutex bu ikki qiymatni qabul qiladigan mantiqiy o'zgaruvchidir: band (to'g'ri) va bepul (noto'g'ri). Agar ip ob'ektga eksklyuziv egalik qilishni xohlasa, u o'z mutexini band deb belgilaydi va u bilan ishlashni tugatgandan so'ng, u mutexni bepul deb belgilaydi. Muteks Java-dagi har bir ob'ektga biriktirilgan. Muteksga faqat Java mashinasi to'g'ridan-to'g'ri kirish huquqiga ega. U dasturchidan yashiringan.

12. Monitor nima?

Monitor - bu maxsus mexanizm (kod bo'lagi) - mutex ustidagi qo'shimcha, u bilan to'g'ri ishlashni ta'minlaydi. Oxir oqibat, ob'ekt band ekanligini belgilashning o'zi etarli emas, biz boshqa iplar band ob'ektdan foydalanishga harakat qilmasligini ham ta'minlashimiz kerak. Java-da monitor kalit so'zi yordamida amalga oshiriladi synchronized. Sinxronlashtirilgan blokni yozganimizda, Java kompilyatori uni uchta kod bilan almashtiradi:
  1. Blokning boshida synchronizedmutexni band deb belgilaydigan kod qo'shiladi.
  2. Blokning oxirida synchronizedmutexni bepul deb belgilaydigan kod qo'shiladi.
  3. Blokdan oldin, synchronizedmutex band yoki yo'qligini tekshiradigan kod qo'shiladi, keyin ip uning chiqarilishini kutishi kerak.
1-qism
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION