В банковском приложении есть метод (транзакция), который служит для перевода денег с одного аккаунта на другой, например: void transfer(Account acc1, Account acc2, int money).
Как реализовать эту транзацию правильно в многопоточной среде?
Например, поставить synchronized для метода transfer - неправильно, потому что в таком случае все аккаунты, ожидающие на трансфер будут на блокировке, пока не выполнится текущий transfer
Отличная задача для разного рода выноса мозга.
1. Обрабатывать транзакции в один поток / одним актором / агентом. Медленно но надёжно.
2. Сделать synchronized на двух объектах, но в предсказуемом порядке. Пример из Java Concurrency In Practice:
if (acc1.hashCode() > acc2.hashCode()) {
synchronized (acc1) { synchronized (ac2) { transferLocked(acc1, acc2) } }
} else {
synchronized (acc2) { synchronized (acc1) { transferLocked(acc1, acc2) } }
}
3. Написать lock-free-дичь
https://www.youtube.com/watch?v=W2dOOBN1OQIhttps://www.youtube.com/watch?v=iQsN_IDUTSc4. Испольховать базу данных, она должна уметь разруливать транзакции и безопасно блокировать таблицы.