Sobes.tech
Middle

Java'da çok iş parçacıklı koleksiyonlar hakkında ne söyleyebilirsiniz?

sobes.tech yapay zeka

AI'dan gelen yanıt

Java'daki çok iş parçacıklı koleksiyonlar, aynı anda birden fazla iş parçacığından gelen verilere güvenli bir şekilde erişim sağlar, yarış koşullarını ve diğer senkronizasyon sorunlarını önler.

Ana arayüzler ve sınıflar şunları içerir:

  • ConcurrentMap: Map'i genişleten ve atomik işlemler sağlayan arayüz.
    • ConcurrentHashMap: Yüksek performanslı uygulama, tüm haritayı değiştirme sırasında kilitlemez. Tam kilitleme olmadan iş parçacığı güvenliği sağlar.
  • CopyOnWriteArrayList ve CopyOnWriteArraySet: İş parçacığı güvenli koleksiyonlar, temel dizinin her değişikliğinde kopyasını oluşturur. Sık okunan ve nadiren değiştirilen koleksiyonlar için uygundur. Okuma kilitlenmeden gerçekleşir.
  • BlockingQueue: Kuyruk arayüzü, kuyruk boş veya dolu olana kadar bekleme işlemlerini destekler. Üretici-tüketici deseni gibi iş parçacıkları arasındaki etkileşimi düzenlemek için kullanılır.
    • ArrayBlockingQueue: Sabit kapasiteye sahip dizi tabanlı BlockingQueue uygulaması.
    • LinkedBlockingQueue: Bağlantılı liste tabanlı, isteğe bağlı kapasite ile BlockingQueue uygulaması.
    • SynchronousQueue: Sıfır kapasiteye sahip kuyruk. Her ekleme işlemi, karşılık gelen çıkarma işlemini bekler ve tam tersi.
  • ConcurrentLinkedQueue: Bağlantılı liste tabanlı, iş parçacığı güvenli Queue uygulaması. Bloke edici işlemleri desteklemez.

Senkronize koleksiyonlardan (Collections.synchronizedList, Collections.synchronizedMap vb.) farkları:

  • Senkronize koleksiyonlar, nesne seviyesinde tam kilitleme kullanır, bu da yüksek rekabet durumlarında performansı azaltabilir.
  • ConcurrentHashMap gibi çok iş parçacıklı koleksiyonlar, daha ince taneli kilitler veya diğer mekanizmalar kullanır, böylece daha iyi performans sağlar.
  • Senkronize koleksiyonların iteratorleri, koleksiyon başka bir iş parçacığı tarafından değiştirilirse ConcurrentModificationException atabilir. Çok iş parçacıklı koleksiyonların iteratorleri genellikle bu tür değişikliklere karşı daha dayanıklıdır.

Belirli bir çok iş parçacıklı koleksiyon seçimi, kullanım senaryosuna bağlıdır: okuma/yazma sıklığı, bloklayıcı işlemlere ihtiyaç, performans gereksinimleri vb.

ConcurrentHashMap kullanım örneği:

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); // İş parçacığı güvenli işlem
    }

    public Integer getValue(String key) {
        return map.get(key); // İş parçacığı güvenli işlem
    }

    public void incrementValue(String key) {
        // Atomik işlem: anahtar yoksa 1 ekler, varsa mevcut değeri artırır
        map.compute(key, (k, v) -> (v == null) ? 1 : v + 1);
    }
}

BlockingQueue kullanım örneği:

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

public class ProducerConsumer {

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

    // Üretici
    public void produce(Integer item) throws InterruptedException {
        queue.put(item); // Kuyruk doluysa bloklar
        System.out.println("Produced: " + item);
    }

    // Tüketici
    public Integer consume() throws InterruptedException {
        Integer item = queue.take(); // Kuyruk boşsa bloklar
        System.out.println("Consumed: " + item);
        return item;
    }
}