Я пишу сервис, который берет два URL urlA
и urlB
, чтобы получить два целых числа a
и b
.Служба возвращает sum
из a
и b
.
. В своей самой простой форме служба работает так:
public Integer getSumFromUrls(String urlA, String urlB) {
Integer a = fetchFromUrl(urlA);
Integer b = fetchFromUrl(urlB);
return a + b;
}
Здесь fetchFromUrl
- синхронная операция, таким образом, он блокирует поток обработки, если значение не доступно.Чтобы сделать вещи эффективнее, я бы предпочел использовать ExecutorService
, чтобы запланировать две выборки и вернуться, когда будут доступны результаты.Вот измененный код (игнорируйте синтаксические нюансы)
public Integer getSumFromUrls(String urlA, String urlB) {
Future<Integer> aFuture = Executors.newSingleThreadScheduledExecutor().submit(new Callable<Integer>() {
public Integer call() {
return fetchFromUrl(urlA);
}
});
Future<Integer> bFuture = Executors.newSingleThreadScheduledExecutor().submit(new Callable<Integer>() {
public Integer call() {
return fetchFromUrl(urlB);
}
});
Integer a = aFuture.get();
Integer b = bFuture.get();
return a + b;
}
Здесь я создал однопотоковых исполнителей для одновременного выполнения запросов.
Поскольку этот код будет выполняться в контексте веб-службы, я, вероятно, не должен создавать однопоточных исполнителей локально внутри функции, а должен использовать пулы потоков N-размера, совместно используемые взапросы.
Мои вопросы здесь:
- Правильно ли вышеприведенное понимание (выделенная курсивом часть)?
- Если да, как мне выбрать оптимальныйразмер пула потоков.Должно ли это быть функцией размера пула потоков моего сервисного контейнера или пропускной способности запроса или того и другого и т. Д.?
- Существует ли лучший способ оптимизации этого сценария, чтобы потоки службы не блокировались при выполнении операций ввода-вывода в большинстве случаев.время.
Примечание: детали, представленные в этом вопросе, не являются полностью реальными сценариями, но представляют тот же набор сложностей, необходимых для ответа на вопрос.