#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 должен быть синхронизирован, поскольку могут быть возможные побочные эффекты, если несколько потоков вызывают его одновременно.
Я надеюсь, что это поможет. 🙂
С уважением.