Sobes.tech
Middle

Ինչ կարող եք ասել Java-ի բազմասահմանի հավաքածուների մասին?

sobes.tech AI

Պատասխան AI-ից

Java-յի բազմատողային հավաքածուները ապահովում են անվտանգ եղանակներ տվյալների հետ աշխատելու համար միաժամանակ մի քանի թելերից, կանխելով մրցակցության պայմանները և այլ սինխրոնիզացիայի խնդիրները:

Հիմնական ինտերֆեյսներն ու դասերը ներառում են՝

  • ConcurrentMap: ընդլայնում է Map-ը և ապահովում է ատոմիկ գործողություններ:
    • ConcurrentHashMap: բարձր կատարողականությամբ իրականացում, որը չի բլոկավորում ամբողջ քարտեզը փոփոխության ժամանակ: ապահովում է թելային անվտանգություն առանց ամբողջական բլոկավորման:
  • CopyOnWriteArrayList և CopyOnWriteArraySet: թելային անվտանգ հավաքածուներ, որոնք ցանկացած փոփոխության ժամանակ ստեղծում են հիմնական զանգվածի պատճենը: լավ են հարմար այն հավաքածուների համար, որոնք հաճախ կարդացվում են և հազվադեպ փոխվում:
  • BlockingQueue: հերթի ինտերֆեյս, որը սպասման գործողություններ է ապահովում, մինչև որ հերթը դատարկ կամ լցված լինի:
    • ArrayBlockingQueue: ֆիքսված ծավալով զանգվածային հիմքով իրականացում:
    • LinkedBlockingQueue: կապակցված ցանկային հիմքով իրականացում, ընտրովի ծավալով:
    • SynchronousQueue: զրո ծավալով հերթ: յուրաքանչյուր ավելացման գործողությունը սպասում է համապատասխան հանման գործողությանը և հակառակը:
  • ConcurrentLinkedQueue: թելային անվտանգ կապակցված ցանկային հիմքով Queue իրականացում, որը չի աջակցում բլոկավոր գործողություններին:

Տարբերությունները սինխրոնիզացված հավաքածուներից (Collections.synchronizedList, Collections.synchronizedMap և այլն):

  • Սինխրոնիզացված հավաքածուները ամբողջական բլոկավորում են օբյեկտի մակարդակով, ինչը կարող է նվազեցնել կատարողականությունը բարձր մրցակցության դեպքում:
  • Բազմատողային հավաքածուները, ինչպիսիք են ConcurrentHashMap, օգտագործում են ավելի մանրամասն բլոկավորում կամ այլ մեխանիզմներ՝ ավելի լավ կատարողականի համար:
  • Սինխրոնիզացված հավաքածուների ինտերատորները կարող են նետել ConcurrentModificationException՝ եթե հավաքածուն փոփոխվի մեկ այլ թելից՝ ինտերացիայի ժամանակ:

Ընտրությունը կոնկրետ բազմատողային հավաքածուի՝ օգտագործման սցենարի վրա է կախված՝ հաճախականությունից, բլոկավորման անհրաժեշտությունից, կատարողականի պահանջներից և այլն:

Օրինակ՝ ConcurrentHashMap-ի օգտագործման օրինակ:

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); // Թելային անվտանգ գործողություն
    }

    public Integer getValue(String key) {
        return map.get(key); // Թելային անվտանգ գործողություն
    }

    public void incrementValue(String key) {
        // ատոմիկ գործողություն՝ եթե բանալի չկա, տեղադրում է 1, հակառակ դեպքում ավելացնում է առկա արժեքը
        map.compute(key, (k, v) -> (v == null) ? 1 : v + 1);
    }
}

Օրինակ՝ BlockingQueue-ի օգտագործման:

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

public class ProducerConsumer {

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

    // Փաստարկային թել
    public void produce(Integer item) throws InterruptedException {
        queue.put(item); // Բլոկավորում է, եթե հերթը լցված է
        System.out.println("Produced: " + item);
    }

    // Խանութի թել
    public Integer consume() throws InterruptedException {
        Integer item = queue.take(); // Բլոկավորում է, եթե հերթը դատարկ է
        System.out.println("Consumed: " + item);
        return item;
    }
}