В моем сервлете я нажимаю несколько URL-адресов, чтобы проверить их статус и вернуть ответ пользователю.Правильная реализация многопоточности Java Future
Захват запросов многопроцессор занимает много времени: нужны потоки и тайм-ауты. Но мне нужны мои потоки, чтобы получить ответ: используя будущее по этой причине.
Мой код очертание:
ExecutorService executor = Executors.newFixedThreadPool(10);
Future<statusModel> future;
for (Map.Entry<String, String> url : urls.entrySet())
{
try
{
future = executor.submit(new CallableRequestStatus(url.getValue()));
status = (statusModel) future.get(5, TimeUnit.SECONDS);
results.add(status);
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());
}
}
executor.shutdownNow();
Все результаты моего отзывной класса приходит в объект состояния, который я позже добавить к ArrayList. Моя проблема в том, что мой подход блокирует меня от запуска всех 10 потоков одновременно. Мне нужно подождать 5 секунд для получения моего объекта статуса, а затем перейти к следующему URL.
Я думаю, что мой подход неисправен. Я пробовал смотреть в Интернете, но я не мог найти ни одного примера с пользовательскими объектами и вовлеченным Arraylist.
Может кто-нибудь помочь мне исправить свою вину. Заранее спасибо
Наконец Обновленный мой код (спасибо Sotirios Delimanolis и Kevin):
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<statusModel>> futures = new ArrayList<Future<statusModel>>();
for (Map.Entry<String, String> url : urls.entrySet())
{
Future<statusModel> future = executor.submit(new CallableRequestStatus(url.getValue()));
futures.add(future);
}
ArrayList<statusModel> results = new ArrayList<statusModel>();
statusModel status;
int i=0;
for (Map.Entry<String, String> url : urls.entrySet())
{
try
{
status = (statusModel) futures.get(i).get(500, TimeUnit.MILLISECONDS);
// do some stuff with status and
if(status.getStatusCode()/100 == 2)
results.add(status);
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());
}
i++;
}
executor.shutdownNow();
System.out.println("Shutdown: "+executor.isShutdown());
Надежда его полезным для кого-то :)
Добавить все фьючерсы в набор или список. После того, как вы отправили все свои вызовы, пройдите через элементы 'Future' и вызовите' get' без значения таймаута. Ваш основной поток будет блокироваться, но другие задачи будут продолжать выполняться. Вы будете в основном ждать длительности самого долгого срока. –
Спасибо Sotirios за быстрый ответ. Я пробовал то, что вы предлагали, но я все еще зацикливаюсь, когда я зацикливаюсь на futureList для серверов, которые занимают слишком много времени. –
Если вам нужно дождаться ответа всех серверов и получить все их результаты, это единственный синхронный способ сделать это. –