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

30. Карточки Яндекс Маркета в одном пуле потоков

Сложная

Java · 48 строк

На странице каталога 48 карточек. Для каждой нужны цена и остаток на складе — два HTTP-запроса по 30 мс, их делают параллельно. Card, Price, Stock и Clients объявлены рядом.

Юнит-тесты на 2 товара зелёные. После выката первая же полная страница не открылась, а потоки сервиса висят в Future.get. Отметьте строки с ошибками.

В работе: Бэкенд выдачи каталога, сборка карточек товара.

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

Источник: наша задача на данных Яндекс Маркета: выдача каталога. Условие пересказано своими словами.

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.ExecutionException;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.Future;
  7. public class CardAssembler {
  8. private final ExecutorService pool = Executors.newFixedThreadPool(8);
  9. private final Clients clients;
  10. private int slowCards = 0;
  11. public CardAssembler(Clients clients) {
  12. this.clients = clients;
  13. }
  14. // Страница каталога: 48 карточек параллельно.
  15. public List<Card> page(List<Long> skus) {
  16. List<Future<Card>> futures = new ArrayList<>();
  17. for (long sku : skus) {
  18. futures.add(pool.submit(() -> card(sku)));
  19. }
  20. List<Card> out = new ArrayList<>();
  21. for (Future<Card> f : futures) {
  22. try {
  23. out.add(f.get());
  24. } catch (InterruptedException e) {
  25. // прервали — пропускаем карточку
  26. } catch (ExecutionException e) {
  27. out.add(Card.stub());
  28. }
  29. }
  30. return out;
  31. }
  32. // Цена и наличие идут параллельно.
  33. private Card card(long sku) throws Exception {
  34. long start = System.nanoTime();
  35. Future<Price> price = pool.submit(() -> clients.price(sku));
  36. Future<Stock> stock = pool.submit(() -> clients.stock(sku));
  37. Card c = new Card(sku, price.get(), stock.get());
  38. if (System.nanoTime() - start > 200_000_000L) {
  39. slowCards++;
  40. }
  41. return c;
  42. }
  43. }