Sobes.tech
Middle

Mida saate öelda Java mitme niidiga kogumite kohta?

sobes.tech AI

Vastus AI-lt

Java mitme niidiga kogumikud pakuvad turvalisi viise andmete töötamiseks mitme niidi samaaegsel kasutamisel, vältides võistlusolukordi ja muid sünkroniseerimisprobleeme.

Põhiliidesed ja klassid hõlmavad:

  • ConcurrentMap: laiendab Map, pakkudes atomaarseid operatsioone.
    • ConcurrentHashMap: kõrge jõudlusega rakendus, mis ei blokeeri kogu kaarti muudatuste ajal. Tagab niiditurvalisuse ilma täieliku lukustamiseta.
  • CopyOnWriteArrayList ja CopyOnWriteArraySet: niiditurvalised kogumikud, mis loovad põhimassiivi koopia igas muudatuses. Sobivad hästi kogumikele, mida sageli loetakse ja harva muudetakse. Lugemine toimub ilma lukustamiseta.
  • BlockingQueue: järjekorra liides, mis toetab ootamisoperatsioone, kuni järjekord muutub tühjaks või täis. Kasutatakse niidudevahelise suhtluse korraldamiseks, näiteks tootja-kasutaja mustris.
    • ArrayBlockingQueue: fikseeritud mahutavusega massiivipõhine BlockingQueue.
    • LinkedBlockingQueue: seotud nimekirja põhjal rakendus, valikulise mahutavusega.
    • SynchronousQueue: nullmahutavusega järjekord. Iga sisestusoperatsioon ootab vastavat väljavõtmise operatsiooni ja vastupidi.
  • ConcurrentLinkedQueue: niiditurvaline seotud nimekirja põhjal rakendus Queue. Ei toeta blokeerivaid operatsioone.

Erinevused sünkroniseeritud kogumike (Collections.synchronizedList, Collections.synchronizedMap jms) ees:

  • Sünkroniseeritud kogumikud kasutavad kogu objekti tasemel lukustamist, mis võib suurendada konkurentsi korral jõudlust vähendada.
  • Mitme niidiga kogumikud, nagu ConcurrentHashMap, kasutavad väiksemat lukustamist või muid mehhanisme parema jõudluse saavutamiseks.
  • Sünkroniseeritud kogumike iteratorid võivad visata ConcurrentModificationException, kui kogumikku muudetakse teise niidi poolt. Mitme niidiga kogumikud on tavaliselt selliste muudatuste suhtes vastupidavamad.

Konkreetse mitme niidiga kogumi valik sõltub kasutusstsenaariumist: lugemis-/kirjutuskiirus, blokeerivate operatsioonide vajadus, jõudlusnõuded ja muud.

ConcurrentHashMap näide:

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); // Niiditurvaline operatsioon
    }

    public Integer getValue(String key) {
        return map.get(key); // Niiditurvaline operatsioon
    }

    public void incrementValue(String key) {
        // Atomaarne operatsioon: kui võti puudub, sisestab 1, vastasel juhul suurendab olemasolevat väärtust
        map.compute(key, (k, v) -> (v == null) ? 1 : v + 1);
    }
}

BlockingQueue näide:

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

public class ProducerConsumer {

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

    // Tootja niit
    public void produce(Integer item) throws InterruptedException {
        queue.put(item); // Blokeerub, kui järjekord on täis
        System.out.println("Produced: " + item);
    }

    // Tarbija niit
    public Integer consume() throws InterruptedException {
        Integer item = queue.take(); // Blokeerub, kui järjekord on tühi
        System.out.println("Consumed: " + item);
        return item;
    }
}