Примечание: эти первые несколько параграфов описывают преднамеренное отсутствие безопасности потока в вопросе, и фактически не отвечают на вопрос, о котором спрашивал спрашивающий ..
Хотя метод проверки и метод извлечения по отдельности являются атомарными, они не объединяются в одну атомарную операцию.
Скажем, муж проверяет учетные записи, находит, что осталось достаточно, а затем отстраняется.
Жена проверяет счета, а затем снимает оставшиеся деньги.
Затем мужу разрешают продолжить, и он пытается снять деньги, но обнаруживает, что жена уже ушла со всем этим.
Редактировать: описывает причину вопроса спрашивающего
Вы не вызываете System.out потокобезопасным способом. Существует условие состязания между вычислением сообщения, которое вы собираетесь отобразить, и фактическим отображением его на консоли - поэтому сообщение жены, вероятно, рассчитывается до ухода мужа, но отображается после него.
Вам необходимо добавить синхронизированные ключевые слова вокруг этих строк System.out (или что-то эквивалентное), если вы хотите устранить этот эффект.
Только представьте, что ваш код на самом деле выглядит так:
String message = Thread.currentThread().getName() + " checks amount : " + amount.get() + ". Remaining ammount after withdrawl should be : " + (amount.get() - amtToWithdraw);
System.out.println(message);
Показывает ли это, где находится состояние гонки?