У меня есть несколько потоков, пытающихся увеличить счетчик для определенного ключа в небезопасной пользовательской структуре данных (которую вы можете изобразить, чтобы быть похожим на HashMap). Мне было интересно, каким будет правильный способ увеличить счетчик в этом случае.Java - вызов функции синхронизированного геттера во время функции синхронизированного сеттера - правильный способ управления общей переменной?
Достаточно ли синхронизировать функцию приращения или мне также нужно синхронизировать операцию получения?
public class Example {
private MyDataStructure<Key, Integer> datastructure = new CustomDataStructure<Key, Integer>();
private class MyThread implements Runnable() {
private synchronized void incrementCnt(Key key) {
// from the datastructure documentation: if a value already exists for the given key, the
// previous value will be replaced by this value
datastructure.put(key, getCnt(key)+1);
// or can I do it without using the getCnt() function? like this:
datastructure.put(key, datastructure.get(key)+1));
}
private synchronized int getCnt(Key key) {
return datastructure.get(key);
}
// run method...
}
}
Если у меня есть два потока, t1, t2, например, я бы что-то вроде:
t1.incrementCnt();
t2.incrmentCnt();
Может ли это привести к какой-либо тупик? Есть ли лучший способ решить эту проблему?
Без взаимоблокировки, но если это единственный метод, который пишет cnt, вы можете просто сделать ++ cnt из incrementCnt() – Shmoopy
Этот код фактически не компилируется. Вы не можете применить оператор '++' к вызову метода. Он должен быть переменной. Это не просто nitpick: такого рода вещи должны сказать вам, что вы делаете это неправильно, по-язычному, даже если механизм потока прекрасен, а это не так. – RealSkeptic
Эти причины включают в себя не позволить использовать вашу собственную небольшую версию atominteger? – Fildor