ConcurrentHashMap поведение и въпроси

Имам 4 нишки - 2 от нишката се актуализират и 2 от нишката четат в concurrentHashMap. Кодът е както следва:

private static ConcurrentHashMap<String, String> myHashMap = new ConcurrentHashMap<>();
private static final Object lock = new Object();

Метод за изпълнение на нишка 1 и нишка 2 (ключът и стойността са низ)

synchronized (lock) {
    if (!myHashMap.containsKey(key)) {
        myHashMap.put(key, value);
    } else {
        String value = myHashMap.get(key)
        // do something with the value
        myHashMap.put(key, value);
    }
}

Методът за изпълнение на Thread 3 и Thread 4 извършва отпечатването

for (Entry<String, String> entry : myHashMap.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println("key, " + key + " value " + value);
}

Има ли някакъв проблем с горното използване на код ConcurrenHashMap? Защото, когато прочетох Javadoc и потърсих в мрежата, намерих следното твърдение:

  1. Този клас е напълно съвместим с Hashtable в програми, които разчитат на неговата безопасност на нишката, но не и на подробностите за синхронизацията. (Забележка – разбирам, че резултатът от нишката за печат може да не е най-новият резултат, но това е добре стига нишката за актуализиране прави нещата правилно.)
  2. Има също някои твърдения за уебсайта, които казват, че един и същ итератор не може да се използва за 2 или повече различни нишки. Така че се чудя дали методът за печат използва същия итератор в 2 нишка по-горе. И защо не можем да използваме един и същ итератор в 2 различни нишки?

Що се отнася до изискването, искам едновременно четене без блокиране, затова избирам ConcurrentHashMap.


person Harry Wang    schedule 17.07.2018    source източник
comment
Има ли проблем с горния код? Не мисля, че можем да отговорим на това, без да знаем точно какво искате да направите и как го правите. Вашият кодов фрагмент е твърде неясен. Вижте stackoverflow.com/help/mcve за инструкции как да направите по-добър примерен код.   -  person Radiodef    schedule 17.07.2018
comment
Актуализира кода. Да направите нещо със стойността просто означава да изчислите стойността.   -  person Harry Wang    schedule 17.07.2018
comment
@Nathan Hughes Добре, трябва да се уверя, че нишката за актуализация е заключена, така че само 1 нишка да може да извърши актуализацията, другата трябва да изчака.   -  person Harry Wang    schedule 17.07.2018
comment
Просто трябва да приемете, че нишката за актуализиране може да бъде атомарно изпълнена само за целия код вътре.   -  person Harry Wang    schedule 17.07.2018
comment
Вие подкопавате цялата цел на CHM, като го използвате под външна ключалка. Вместо това използвайте атомния merge().   -  person shmosel    schedule 17.07.2018
comment
Не мисля, че наистина можем да предложим compute или merge, без да знаем какво всъщност прави нещо със стойността.   -  person Radiodef    schedule 17.07.2018
comment
Не забравяйте, че цялата цел на използването на CHM в този случай е да се постигне неблокиращо четене/печат.   -  person Harry Wang    schedule 17.07.2018
comment
Наскоро попаднах на тема с подобна публикация; може би това ще изясни съмненията ви: Java concurrent hashMap retrieval   -  person prasad_    schedule 17.07.2018


Отговори (1)


Вместо да използвате блока if else, можете да използвате метода putIfAbsent от паралелната hashmap и второто нещо, което не трябва да използвате външното заключване в паралелната hashmap.

person Dinesh    schedule 17.07.2018
comment
Работата е там, че не мога да използвам вградения метод putIfAbsent поради сложността на изчислението. А защо да не използваме външно заключване? Има ли някакво неочаквано поведение при използване на външно заключване? или просто поради производителността? Обзалагам се, че производителността не може да бъде по-лоша от използването на Hashtable, която блокира дори при четене на нишка. - person Harry Wang; 17.07.2018