Многопоточный доступ к коллекции Java

147
24 сентября 2019, 16:20

Начал изучать многопоточность в Java и возник следующий вопрос: У меня есть некая коллекция, допустим map, которая содержит объекты Account c полем flot money = 100; Я хочу запустить 4 потока, которые будут переводить money c одного рандомного Acc на другой рандомный Acc. Я так понимаю когда я выберу рандомно два Acc следующие операции нужно обернуть в synchronized или lock(list содержит все ключи map, он Collections.synchronizedList, round() - моя функция округления до двух знаков):

lock.writeLock().lock();
try {
    String idFrom = StartInit.listRandom.get(rnd.nextInt(StartInit.listRandom.size()));
    String idTo = StartInit.listRandom.get(rnd.nextInt(StartInit.listRandom.size()));
    float moneyTransfer = round(rnd.nextFloat() * Math.min(getAccountMoney(idFrom), getAccountMoney(idTo)), MAX_MONEY_SCALE);
    setAccountMoney(idFrom, getAccountMoney(idFrom) - moneyTransfer);
    setAccountMoney(idTo, getAccountMoney(idTo) + moneyTransfer);
} finally {
    lock.writeLock().unlock();
}

Но тогда получается смысл многопоточности теряется, так как доступ будет к map с Acc-ми предоставляться последовательно. Возможно есть более красивые и более действенные методы сделать это многопоточно?

Answer 1

Надо лочить конкретные эккаунты, а не иметь один общий лок. Т.е. в каждом эккаунте должен быть свой лок, который надо захватить. Так как надо захватить 2 аккаунта (как минимум) - то захват локов надо проводить строго попорядку- например по номеру счета (сначала с меньшим номером - потом с большим). Иначе получите дедлок. Скорость увеличится за счет того, что если в двух транзакциях разные счета, то операции пройдут независимо друг от друга.

READ ALSO
Как самому сделать вход , не через loadUser для oauth2

Как самому сделать вход , не через loadUser для oauth2

Я не знаю почему, но вк не работает для Security 5

145
Непонятная конструкция в объектах

Непонятная конструкция в объектах

Начал не так давно изучать язык JAVAПросматривая разные туториалы и примеры программ, неоднократно сталкиваюсь с непонятными для меня конструкциями

147
Insert Into SQLite

Insert Into SQLite

я добавляю значение в таблицу с помощью INSERT INTO USERS

170
Проблема с ConstraintLayout в Android

Проблема с ConstraintLayout в Android

Постараюсь вкратце описать сложившуюся ситуациюКаковы исходные данные? Представим себе довольно-таки простенький макет, корневым элементом...

158