Допустим, у меня есть класс, у которого есть два метода calculateBonus(Account a)
и calculatePenalty(Account a)
.
Допустим, я добавил ключевое слово synchronized
к методам или у них есть блок synchronized(this)
внутри методов.Означает ли это, что если какой-либо поток рассчитывает бонус на счете, никакой другой поток не может рассчитать штраф на другом счете, пока не будет начислен бонус?
Штрафы и бонусы различны и сложны, возможно, чтоучетная запись может получить оба.Неважно, в каком порядке они рассчитываются (существует предельная дата, поэтому одно не влияет на результат другого), но крайне важно, чтобы я не пытался рассчитывать оба на одном и том же счете одновременно (для очевидных данныхИз соображений согласованности в каждом методе обновляются статусы и информация журнала аудита.
Как лучше всего спроектировать мой код, чтобы я мог БЕЗОПАСНО максимизировать параллельную обработку?
IДо сих пор рассматривали следующие варианты:
1) Поместите код, который рассчитывает бонусы и штрафы в разных классах, и используйте ключевое слово synchronized
в методе.Не нравится эта идея, потому что есть некоторые общие сложные функции, которые я хотел бы сохранить вместе, они не связаны с вводом-выводом и выполняются быстро, поэтому не влияют на производительность.
2) Синхронизация на переданных в Account
параметр.Если я правильно понимаю, это означает, что я не могу рассчитать бонус на другом счете, выполняющемся в другом потоке, пока бонус не будет рассчитан на первом счете в первом потоке.Но я мог бы рассчитать штраф для другого аккаунта в другом потоке - только не для аккаунта с тем же .Мне это нравится больше всего, но я хочу быть уверенным, что правильно его понимаю.
3) Создайте объект внутренней частной блокировки для каждого метода, который я хочу синхронизировать: один для бонусов и один для штрафов.Если вы правильно понимаете это, это означает, что только один поток может рассчитывать бонус за один раз, но это не не препятствует другому потоку рассчитывать штраф на тот же аккаунт в то же время.
Теперь я понимаю, что должен быть осторожен, чтобы избежать тупика, я планирую убедиться, что ничто внутри любого синхронизированного блока не зависит от вызовов других синхронизированных методов.Я также намерен убедиться, что любая локальная переменная, используемая в вычислениях, которая влияет на конечное значение, находится внутри синхронизированного блока.