Sobes.tech
Middle

Yarış şərti (race condition) haqqında danışın və çox ipli tətbiqlərdə necə qarşısını almaq olar.

sobes.tech Süni İntellekt

AI-dan cavab

Yarış vəziyyəti çox iş parçacığı sistemlərində dizayn qüsurudur və proqramın icra nəticəsi müxtəlif iş parçacıqlarının kod hissələrini icra etmə ardıcıllığından asılıdır. Bu, bir neçə iş parçacığının eyni zamanda paylaşılan dəyişkən resursa düzgün sinxronizasiya olmadan müraciət etdikdə baş verir.

Java-da yarış vəziyyətlərinin qarşısını almaq üçün aşağıdakı yanaşmalar istifadə olunur:

  1. Sinxronlaşdırılmış metodlar və bloklardan istifadə:

    class Counter {
        private int count = 0;
    
        // Sinxronlaşdırılmış metod
        public synchronized void increment() {
            count++;
        }
    
        // Sinxronlaşdırılmış blok
        public void decrement() {
            synchronized (this) {
                count--;
            }
        }
    }
    

    synchronized açar sözü, bu obyekt üçün (və ya statik metod olarsa, sinif üçün) yalnız bir iş parçacığının sinxronlaşdırılmış kodu icra etməsini təmin edir.

  2. java.util.concurrent.locks paketindən Lock sinifindən istifadə:

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class SafeCounter {
        private int count = 0;
        private final Lock lock = new ReentrantLock();
    
        public void increment() {
            lock.lock(); // Bloklanmanı əldə etmək
            try {
                count++;
            } finally {
                lock.unlock(); // Bloklanmanı azad etmək
            }
        }
    }
    

    Lock synchronized ilə müqayisədə daha çevik kilidləmə mexanizmləri təqdim edir.

  3. java.util.concurrent.atomic paketindən atomik dəyişənlərdən istifadə:

    import java.util.concurrent.atomic.AtomicInteger;
    
    class AtomicCounter {
        private AtomicInteger count = new AtomicInteger(0);
    
        public void increment() {
            count.incrementAndGet(); // Atomik əməliyyat
        }
    }
    

    Atomik dəyişənlər atomik əməliyyatlar (məsələn, artırma, azaldma) təmin edir və bunlar tək bir vahid kimi icra olunur və digər iş parçacığı tərəfindən kəsilə bilməz.

  4. java.util.concurrent paketindən iş parçacığı təhlükəsiz kolleksiyalardan istifadə: Məsələn, ConcurrentHashMap, CopyOnWriteArrayList. Bu kolleksiyalar çox iş parçacığı mühitində təhlükəsiz istifadə üçün hazırlanmışdır.

  5. Paylaşılan dəyişkən vəziyyətlərdən qaçınmaq: Əgər mümkünsə, çox iş parçacığının əlçatan məlumatlar dəyişməz (immutable) edilməli və ya hər iş parçacığı üçün ayrılmalıdır.

  6. volatile istifadə: volatile açar sözü, dəyişənin bütün iş parçacılarına dəyişikliklərin görünməsini təmin edir, lakin əməliyyatların atomikliyini təmin etmir (yalnız primitiv tiplərin oxunması və yazılması üçün, long və double istisna olmaqla, və referanslar üçün). Bu, digər mexanizmlərlə və ya sadə, vəziyyətdən asılı olmayan əməliyyatlar üçün faydalıdır.

    class VolatileFlag {
        volatile boolean flag = false; // Görünmə təmin edilir
    
        public void setFlag() {
            flag = true;
        }
    
        public boolean isFlag() {
            return flag;
        }
    }
    

Uyğun metodun seçimi konkret vəziyyətə və performans və mürəkkəblik tələblərinə bağlıdır.