Как отключить блокировку потока при загрузке файла при использовании сторонней библиотеки - PullRequest
0 голосов
/ 18 февраля 2019

Мое приложение использует eBay Picture Service для загрузки изображений с моего рабочего стола на сервер eBay.Обычно загрузка занимает несколько секунд.Однако иногда это может занимать часы, а иногда и никогда не завершится.Когда это произойдет, непредсказуемо, и API не выдает никаких исключений.Это заставляет мое приложение вызывать внешний API слишком много раз одновременно, а также забирает системные ресурсы.

Моя цель - установить тайм-аут для загрузки и отменить базовый процесс, если загрузка не удалась в течение определенного времени.Я попытался установить тайм-аут на ExecutorService и затем отменить future, когда выдается исключение, как предложено в этом и этом сообщении:

ExecutorService executorService = Executors.newFixedThreadPool(10);

ArrayList<Future<?>> futuresList = new ArrayList<Future<?>>();


for (String singleTask : taskList) {

futuresList.add(executorService.submit( new Runnable(){      
              @Override
              public void run(){
               try {
                myBlockingTask(singleTask);
            } catch (IOException | InterruptedException | ExecutionException e) {
                    e.printStackTrace();
            }
              }
         }));               
}


try {
    future.get(240, TimeUnit.SECONDS);
} catch (Exception e){
    e.printStackTrace();

  // Stops parent thread from waiting for child but it does not terminate 'child' thread. 
  // As a result, call(s) to external API continue to increase (rapidly) since the underlying process never actually ends
    future.cancel(true); 
    }

К сожалению, это решение работает только тогда, когда основной поток продолжает работать из-за бесконечного цикла и / или основная операция предназначена для понимания Thread.isInterrupted() (как в цикле while()).В этом случае, однако, я не контролирую основной процесс, поэтому я не могу вызвать прерывание в дочернем потоке.API также не предоставляет метод тайм-аута.

Есть ли способ принудительно завершить операцию блокировки в этом примере?

Спасибо!

1 Ответ

0 голосов
/ 19 февраля 2019

Прежде всего, я бы порекомендовал вам сделать дамп потока, чтобы найти точное место, которое зависает.А пока попробуйте посмотреть на исходный код библиотеки, которую вы используете, пытаясь понять, что может вызвать это зависание.Скорее всего, библиотека вызывает что-то, что не отвечает за прерывание.К счастью, таких операций не так много, и большинство из них связаны с сокетным вводом-выводом.Самый полный список JDK, который я когда-либо видел, представлен в главе 7.1.6 книги «Практика Java-параллелизма».Socket I / O выглядит как разумное объяснение для вашего случая, потому что клиентская библиотека наверняка вызывает ebay API через HTTP.Если он использует стандартный HTTP-клиент JDK, попробуйте установить эти таймауты .В противном случае единственно возможное решение состоит в том, чтобы изменить исходный код библиотеки, чтобы сделать его ответственным за прерывание, или использовать другой:)

...