Sobes.tech
Middle

Java-da çox iplikli kolleksiyalar haqqında nə deyə bilərsiniz?

sobes.tech Süni İntellekt

AI-dan cavab

Java-da çox iplikli kolleksiyalar çox iplikli məlumatlarla işləmək üçün təhlükəsiz yollar təqdim edir, yarış vəziyyətlərinin və digər sinxronizasiya problemlərinin qarşısını alır.

Əsas interfeyslər və siniflər aşağıdakılardır:

  • ConcurrentMap: Map-i genişləndirir və atomik əməliyyatlar təmin edir.
    • ConcurrentHashMap: Yüksək performanslı implementasiya, dəyişiklik zamanı bütün xəritəni bloklamır. Tam bloklama olmadan çox iplikli təhlükəsizlik təmin edir.
  • CopyOnWriteArrayListCopyOnWriteArraySet: Çox iplikli kolleksiyalar, hər dəyişiklikdə əsas massivin nüsxəsini yaradırlar. Tez-tez oxunan və az dəyişən kolleksiyalar üçün uyğundur. Oxuma bloklamasız həyata keçirilir.
  • BlockingQueue: Gözləmə əməliyyatlarını dəstəkləyən növbə interfeysi, növbə boş və ya tam olduqda gözləyir. İki iplik arasında qarşılıqlı əlaqəni təşkil etmək üçün istifadə olunur, məsələn, producer-consumer nümunəsində.
    • ArrayBlockingQueue: Sabit tutuma malik massiv əsaslı BlockingQueue implementasiyası.
    • LinkedBlockingQueue: Bağlı siyahı əsaslı BlockingQueue implementasiyası, opsional tutuma malik.
    • SynchronousQueue: Sıfır tutumlu növbə. Hər bir əlavə əməliyyatı müvafiq çıxarış əməliyyatını gözləyir və əksinə.
  • ConcurrentLinkedQueue: Bağlı siyahı əsaslı çox iplikli təhlükəsiz Queue implementasiyası. Bloklama əməliyyatlarını dəstəkləmir.

Senkronlaşdırılmış kolleksiyalardan (Collections.synchronizedList, Collections.synchronizedMap və s.) fərqləri:

  • Senkronlaşdırılmış kolleksiyalar obyekt səviyyəsində tam bloklama istifadə edir, bu da yüksək yarışma şəraitində performansı azalda bilər.
  • ConcurrentHashMap kimi çox iplikli kolleksiyalar daha incə bloklama və ya digər mexanizmlər istifadə edir, daha yaxşı performans əldə etmək üçün.
  • Senkronlaşdırılmış kolleksiyaların iteratorları kolleksiya dəyişdirildikdə ConcurrentModificationException atə bilər. Çox iplikli kolleksiyaların iteratorları adətən bu cür dəyişikliklərə daha davamlıdır.

Xüsusi çox iplikli kolleksiyanın seçimi istifadə ssenarisindən asılıdır: oxuma/yazma tezliyi, bloklama əməliyyatlarının ehtiyacı, performans tələbləri və s.

ConcurrentHashMap istifadə nümunəsi:

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentExample {

    private final ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

    public void updateValue(String key, Integer value) {
        map.put(key, value); // Çox iplikli təhlükəsiz əməliyyat
    }

    public Integer getValue(String key) {
        return map.get(key); // Çox iplikli təhlükəsiz əməliyyat
    }

    public void incrementValue(String key) {
        // Atomik əməliyyat: əgər açar yoxdursa, 1 yerləşdirir, əks halda mövcud dəyəri artırır
        map.compute(key, (k, v) -> (v == null) ? 1 : v + 1);
    }
}

BlockingQueue istifadə nümunəsi:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;

public class ProducerConsumer {

    private final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

    // İplik-istehsalçı
    public void produce(Integer item) throws InterruptedException {
        queue.put(item); // Bloklanır, əgər növbə tamdır
        System.out.println("Produced: " + item);
    }

    // İplik-istehlakçı
    public Integer consume() throws InterruptedException {
        Integer item = queue.take(); // Bloklanır, əgər növbə boşdursa
        System.out.println("Consumed: " + item);
        return item;
    }
}