Разберись, как работает программа.
Во время тестирования лог содержит следующее:
.....
Добавляем 1000, на счету 1000
Тратим 100, на счету 800
Тратим 100, на счету 800
Тратим 100, на счету 800
Тратим 100, на счету 700
.....
Создан баг: Деньги не правильно списываются со счета.
Найти и исправить ошиб
Банкомат
- 9
- Недоступна
Комментарии (223)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Romanya System Engineer
позавчера, 13:16
Промотал коменты до самого конца, так и не нашел ответ на этот вопрос.
Вот есть такая лекция: тут
В ней такие строки:
Смотрю я на вот это:
И думаю, ну вот она эта ситуация. Добавил volatile к переменной balance. В надежде на то что 3 потока будут менять эту переменную но все будут видеть её новое значение и повторяющихся вычитаний не будет. Ан нет не работает. Почему где ошибаюсь подскажите?
P.S (конечно решил с помощью sync и валидатора но хотелось бы разобраться)
P. P. S (есть идея о том что потоки как бы не напрямую взаимодействуют с переменной, а через метод внутри класса. Но никаких фактов я про это не нашел)
P. P. P. S (еще есть идея про то что методы переопределяют ссылку на эту переменную)

+2
VasliyD 19 уровень, Москва
1 марта, 13:58
Не дочитав до конца задание, поставил sync на account в расходном и приходном run. По идее так ведь тоже можно? Правда, валидатор не принял, заставил сделать как велено.
0
Flexo Bending Unit #3370318
23 февраля, 09:55
Ну что тут можно сказати. Можно не читать условия, прочитать требования и добавить нужные ключи куда написано. Поздравляю, задача решена, действительно "лёгкая". Следующая!
А можно попытаться вникнуть в механику задачи, и осознать, что из условия непонятно, какой баг, куда, почему, что требуется-то? Хотя бы потому, что по условию добавляли по 100, тратили по 1000, в задаче ровно наоборот. И в чём баг заключается, нужно поменять эти циферки местами? Где там что теряется? Ничего непонятно.
Вроде становится всё более менее на свои места, если прогнать задачу с маркерами тредов (см ниже комментарий уважаемого @Kes) и внимательно посмотреть на вывод. И то, не с первого раза можно заметить, что там что-то не так (если треды начнут работать в строгой очерёдности, чисто случайно).
0
Flexo Bending Unit #3370318
23 февраля, 10:02
Вот правильный вывод, чего хотели добиться составители задачи после решения:
а вот что было:
- после пополнения счёта бывало, что недостаточно денег (но редко, я за первые два прогона этого не увидел)
- треды-расходники тратили больше денег, чем их было на счёте, потому что переменная balance объекта account не успевала обновляться, т.к. не была синхронизирована. это, по всей видимости, по условию и является багом, но названо "При списании денег со счета теряются деньги."
+1
Дмитрий 18 уровень
22 февраля, 11:11
Сначала я решил, что раз тратят деньги 3 потока, а добавляет всего один, то синхронизировать нужно трату, но Валера сказал НЕТ - твоя логика не верна. Видимо потому что метод "deposit(BigDecimal money)" не атомарный, осуществляется в несколько этапов: создать переменную, получить текущее состояние банковского счета, увеличить его на значение "money", вывести на экран уведомление о том, что операция выполнена (хотя фактически это не так), присвоить переменной банковского счета новое значение. Мы как бы говорим потокам, тратящим бабло: парни погодите минуточку, не суетитесь, деньги начали поступать на счет)
0
Даниил Александрович 25 уровень, Тамбов
3 февраля, 06:20
разработчик который мутит много поточный банкомат надо на нобелевскую.
работа со счетами в потоках в банке имеет ли смысл? у счета 1 бенифицар. это как файловая система. читать могут все, но как только приходит запрос на запись сразу накладывается lock. и все что проиходит четко только в порядке очереди.
0
Vladimir Shevchenko 22 уровень, Днепр
23 января, 06:21
Подскажите что это такое в классе банкомат, статический блок или что это???:
private static Thread addMoney = new Thread() {
...
};
0
Бельчонок Изи 23 уровень, Казань
23 января, 12:35
Я думаю, что это так называемый анонимный класс. Когда при создании объекта сразу прописывается реализация его метода.
+1
Максим Дудин 20 уровень, Калининград
23 декабря 2020, 19:41
В идее, в исходном варианте, у меня задача работает исключительно корректно... видимо частный случай, поэтому и залез посмотреть комментарии дабы убедиться в чём подвох..
+1
Булат 28 уровень, Москва
22 декабря 2020, 20:02
Не уверен, что правильно, но объяснил для себя так (после примитивного добавления модификаторов):
Методы withdraw и deposit вызываются на объекте account
Который является общим статическим для наших потоков. Т.е. добавили synchronized для методов - ака сказали, что метод синхронный на объекте this, т.е. account - лок.
Поэтому (этот кусок инфа было непросто найти и переварить) при вхождении одного потока spendThread в sync метод withdraw (например) другие потоки spendThread2,3, etc. будут ожидать первый и не смогут вообще никакие другие sync блоки/методы этого объекта исполнять.
Т.е. потоки теперь после установки модификаторов поочередно дергают объект на котором залочены его конкретные методы - в нашем случае аккаунт. Поправьте если не прав.
P.S. Изначаль рассуждал, что если поточные переменные разные
spendThread
spendThread1
spendThread2, то и независимо все должно исполняться, но нет надо смотреть конкретно что за объект this на котором вызываются sync методы +2
Future Man 25 уровень
29 декабря 2020, 10:14
ну да кинул блок synhronized на account в run - результат тот же, что и если кинуть deposit и withdraw
+2
Игорь HDL developer в Y
16 декабря 2020, 15:21
Задача показательная, хотя статичность банковского счета смущает. Концептуально данный банкомат работает с одним единственным счетом, это весьма странно.
0
Евгений 22 уровень, Новосибирск
6 декабря 2020, 02:55
Комрадос, а может кто-то просветить, что за синтаксис такой диковинный со стрелочкой? Вроде, раньше в задачах не попадался.
![]()

0
Паровозик, который смог 34 уровень, Москва
23 декабря 2020, 11:42
Надо нажать на нее, и она раскроется :)
Просто "компактит" код в нечто меньшее по объёму.
0
Сергей Ткачев Java Developer
9 января, 17:43
В каком-то смысле, конечно, "компактит" :)) Это "лямбда" - оч. популярная штука в Java. Просто мы до нее еще не дошли. Работает с функциональными интерфейсам - т.е. когда есть интерфейс с одной функцией. Соответсвенно имя функции можно скрыть - она и так известна. Вот классное видео на тему - Лямбда-выражения
+2