Банкомат

  • 9
  • Недоступна
Разберись, как работает программа Во время тестирования лог содержит следующее: ..... Добавляем 100, на счету 1100 Добавляем 100, на счету 1200 Тратим 1000, на счету 100 Недостаточно денег ..... Создан баг: При списании денег со счета теряются деньги Найти и исправить ошибку
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (97)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Максим20 уровень, Черкассы
пятница, 11:37
не понятно. Что должно поменяться? У меня с синхронизаторами в разных местах и без них ничего не меняется. Выглядит одинаково.
Тратим 100, на счету 300
Тратим 100, на счету 200
Тратим 100, на счету 100
Тратим 100, на счету 0
Недостаточно денег
Недостаточно денег
В условии задачи речьидет о какой-то потере ста денег, причем 100 прибавляем, а тысячку вычитаем...
Во время тестирования лог содержит следующее:
.....
Добавляем 100, на счету 1100
Добавляем 100, на счету 1200
Тратим 1000, на счету 100
Недостаточно денег
John Doe18 уровень, Одесса
1 августа, 10:24
Сначала валидатор бьет по рукам за любое отклонение от условий задачи. Потом для исправления бага "При списании денег со счета теряются деньги." нужно исправить ещё и метод, зачисляющий деньги на счет. Не надо так.
Alexandr Racov23 уровень
6 июня, 17:56
А разве не должен еще и метод deposit синхронизироваться? Ведь, если Один из потоков будет снимать деньги, а в это время поток addMoney может закидывать денег, можем получить неожиданный результат. Доступ к изменению переменной balance у нас имеют оба метода и deposit и withdraw.
Павел20 уровень, Санкт-Петербург
31 мая, 09:47
newBalance.compareTo(BigDecimal.ZERO) < 0
а что значит биг синимал ЗЕРО??? я уже весь инет облазал.....
Игорь Ким31 уровень, Тольятти
3 июня, 16:50
Константа класса BigDecimal равная нулю
Павел20 уровень, Санкт-Петербург
3 июня, 18:26
спасибо))
fedor20 уровень, Москва
18 апреля, 20:22
сцк, лямбдами уже кроют...
private static Thread addMoney =  run() -> {
Wladyslaw19 уровень
21 июля, 12:44
Это анонимный класс, вроде как
Nail25 уровень, Кельн
25 июля, 21:31
ложная тревога, это еще не лямбда
Serhii Harasymiv26 уровень
21 марта, 07:06
Це нормально що я мало що можу розібрати в цьому коді, не маючи досвіду програмування взагалі?))) дуже сильно демотивує))
Alexander Fominsky20 уровень, Санкт-Петербург
9 июля, 16:05
Джавараш вообще учит побольше гуглить, поменьше писать. Подозреваю что готовят к реальной жизни. Типа "Ваша задача не код разбирать, а решение сделать": •В методе withdraw(BigDecimal money), если необходимо, используй synchronized. •В методе deposit(BigDecimal money), если необходимо, используй synchronized. Слишком просто.
TheDIP23 уровень, Киев
15 февраля, 17:54
Вообщем что я понял из разбора задачи, может кто-то тоже над этим думает. Обьект(статическая переменная), в нашем случае
static BankAccount account = new BankAccount("Amigo");
МОЖЕТ использоваться для вызова 1) синхронизированного 2) и не синхронизированного методов одновременно (разными потоками) Рефер на документацию: First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object. https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html Правда тут сказано про 2 синхронизированных метода, что они не могут использоваться, но я протестил и синхронизированный и не синхронизированный могут. Такие дела.
Alexander20 уровень, Москва
3 февраля, 15:45
Если я все правильно понял, то: 1. Гонка сигналов во время снятия/занесения денег на аккаунт 2. Из условий задачи деньги заносяться раз в секунду, а сниматься должны раз в 0.1 секунду. Соответственно запретить снятие чаще, чем раз в 0.1 секунду.
Mikhail Uchakov26 уровень, Санкт-Петербург
22 января, 09:31
Валидатор принимает решение только при изменении двух методов в классе BankAccount. Читайте внимательно требования к задаче.
Игорь22 уровень, Нижний Новгород
31 декабря 2018, 09:20
Не понятно почему не срабатывает синхронизация внутри метода withdraw:
public void withdraw(BigDecimal money) throws NotEnoughMoneyException {
     synchronized (balance) {
          BigDecimal newBalance = balance.subtract(money);
          if (newBalance.compareTo(BigDecimal.ZERO) < 0) throw new NotEnoughMoneyException();
          balance = newBalance;
          System.out.println("Тратим " + money + ", на счету " + balance);
     }
}
В таком варианте есть возможность вывода:
Тратим 100, на счету 400
Тратим 100, на счету 200
Тратим 100, на счету 200
Тратим 100, на счету 100
Тратим 100, на счету 0
Хотя и изменение переменной и ее вывод внутри одного блока synchronized. Приходится синхронизировать на уровне всего объекта - т.е. добавлять synchronized в сигнатуру метода:
public synchronized void withdraw(BigDecimal money)
Хотя никак не понимаю почему в первом варианте может быть такой баг - ведь у нас все нити используют один объект BankAccount и в нем изменение переменной и ее вывод неразделимы.
Евгений18 уровень, Санкт-Петербург
5 августа, 10:04
Если я правильно понимаю, то balance, является BigDecimal, а это неизменяемый (immutable) объект, поэтому ставить на него мьютекс бесполезно, если он будет изменяться в этом блоке.