Войти Регистрация
Конкурентность

19. Кэш курсов валют с double-checked locking

Средняя

Java · 43 строк

RatesCache отдаёт курсы для экрана обмена валюты. rate и convert вызываются из 200 потоков веб-сервера, refresh — из планировщика раз в минуту. Источник курсов отвечает за 150–400 мс.

Отметьте строки с ошибками.

В работе: Экран обмена валюты в мобильном банке.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Плюс 1 вопрос про поведение программы — на зачёт не влияют. Ответ один на подход: после него показываем разбор.
double-checked lockingvolatileбезопасная публикацияHashMap

Источник: на задачах Альфа-Банка: обмен валюты в приложении. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. import java.math.BigDecimal;
  2. import java.math.RoundingMode;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class RatesCache {
  6. private static Map<String, BigDecimal> rates;
  7. private final RatesClient client;
  8. public RatesCache(RatesClient client) {
  9. this.client = client;
  10. }
  11. public BigDecimal rate(String currency) {
  12. if (rates == null) {
  13. synchronized (RatesCache.class) {
  14. if (rates == null) {
  15. rates = new HashMap<>();
  16. rates.putAll(client.fetchAll());
  17. }
  18. }
  19. }
  20. return rates.get(currency);
  21. }
  22. // Планировщик вызывает раз в минуту.
  23. public void refresh() {
  24. synchronized (RatesCache.class) {
  25. rates.clear();
  26. rates.putAll(client.fetchAll());
  27. }
  28. }
  29. // Сколько валюты получит клиент за сумму в рублях.
  30. public BigDecimal convert(BigDecimal amountRub, String currency) {
  31. return amountRub.divide(rate(currency), 2, RoundingMode.HALF_UP);
  32. }
  33. }
  34. interface RatesClient {
  35. Map<String, BigDecimal> fetchAll();
  36. }