Потокобезопасный для изменения элементов

#java #multithreading #concurrency #concurrentskiplistmap

#java #многопоточность #параллелизм #concurrentskiplistmap

Вопрос:

У меня есть приведенный ниже код, добавление выглядит для меня потокобезопасным. Как насчет modifyelement или как я могу сделать этот потокобезопасным?

 ConcurrentNavigableMap<String, List<String>> entries = new ConcurrentSkipListMap<>();
  
 public void record(String key, String value) {
    entries.computeIfAbsent(key, k -> Collections.synchronizedList(new ArrayList<String>())).add(value);
}



    public void modifyelement(String key, String oldval, String newval) {
        entries.computeIfPresent(key, (k , v ) -> {
                v.set(v.indexOf(oldval), newval);
                return v;
            });
        
    }
 

Комментарии:

1. добавление выглядит для меня потокобезопасным , и тот факт, что в документации говорится: «Не гарантируется, что функция будет применена один раз атомарно …» вас не пугает?

Ответ №1:

Java использует концепцию монитора для обеспечения потокобезопасности, когда это необходимо. Проще говоря, критические переменные обрабатываются как замкнутое пространство, называемое монитором. Когда поток вызывает что-то, содержащее критические переменные, он получает контроль над монитором. Если другой поток хочет войти в монитор сейчас, он должен подождать, пока первый поток не покинет критическое пространство.

Вы можете пометить метод как критическое пространство, используя synchronized ключевое слово. Пример:

public synchronized void doSomething() {}

Это гарантирует, что только один поток может использовать метод. Имейте в виду, что существуют альтернативные способы обеспечения потокобезопасности, такие как блокировки, устанавливаемые вручную.

Теперь к вашему конкретному примеру, modifyelement должен быть синхронизирован, поскольку могут быть возможные побочные эффекты, если несколько потоков вызывают его одновременно.

Я надеюсь, что это поможет. 🙂

С уважением.