Использовать СУБД. Это только первые грабли, на которые вы начинаете наступать. Ваше решение плохо поведет себя, если программа упадет. Может получиться так, что деньги спишутся, а заказ не запомнится или наоборот. Причем нужна СУБД с поддержкой транзакций, модные нынче noSQL решения не подойдут или вы напишите поверх них свой транзакционный движок (в документации к mongodb есть пример).
Ну или, если очень хочется, надо переписать
checkCompanyBalance(company.getBalance(), order.getSum());
так, чтобы он входил в критическую секцию (захватывал бы мьютекс, принадлежащий объекту компании), проверял баланс, если денег достаточно, вычитал из баланса сумму, прописывал в список транзакций сообщение, за что было начато списание денег, после чего записывал бы всю эту информацию в энергонезависимую, резервируемую на несколько машин память и, наконец, отпускал мьютекс. Затем создаем заказ, записываем его на такое же надежное хранилище. И, после этого, снова лезем в объект компании и помечаем транзакцию как выполненную.