Смешается смешная вещь ... receorcompletionservice
-
10-10-2019 - |
Вопрос
У меня есть приложение, написанное на Java, которое необходимо найти всех достижимых хостов в сети.
я использую InetAddress.isReachable()
сделать это с тайм -аутом 2000 миллисекунд.
Я смотрю IP -адрес текущей локальной машины и исходя из того, что я пытаюсь достичь других IP -адресов, которые заканчиваются 1 - 255, пропускающими IP -адрес локальных машин.
Все работает отлично, один резьба, просто занимает много времени, так как большинство IP -адресов не доступны, поскольку они не существуют, поэтому используйте 2 второго тайм -аута.
Чтобы ускорить ситуацию (и попробуйте параллелизм в действии :: Брайан Гетц) я попытался использовать Future
а также Callable
и т.п.
Все это тоже прошло хорошо.
Однако мне показалось, используя ExecutorCompletionService
Чтобы дать моим пользователям более отзывчивое приложение, чтобы они могли видеть результаты, когда они стали доступными, используя
Future<Reach> reachedFuture = completionService.take();
Запуск этого на одномпроцессорном компьютере со следующей конфигурацией вызывает идентифицировать только 1 из четырех достижимых хостов:
private static final int poolSize = 10;
private static final int maxPoolSize = 10;
private static final long keepAliveTime = 120;
private static final LinkedBlockingQueue<Runnable> queue
= new LinkedBlockingQueue<Runnable>(20);
private static final ExecutorService executorService
= new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
private static final CompletionService<Reach> completionService
= new ExecutorCompletionService<Reach>(executorService);
Изменение его на четырехъядерную машину также заставило его обнаружить все достижимые хосты:
private static final int poolSize
= Math.max(2,Runtime.getRuntime().availableProcessors());
private static final int maxPoolSize
= Math.max(2,Runtime.getRuntime().availableProcessors());
Изменяя InetAddress.isReachable()
Тайм -аут до 10 секунд сделал последний конфигуратор.
Также изменяя конфигурацию следующим образом на квад -основной машине, также заставили его работать с 2 -секундным тайм -аутом:
private static final int poolSize = 2;
private static final int maxPoolSize = 2;
Я упускаю что -то очень очевидное, почему это происходит?
Что останавливается InetAddress.isReachable(2000)
От обнаружения всех достижимых хостов в моей сети?
Почему попытка запустить несколько InetAddress.isReachable()
Вызовы не проходят?
Решение
Поэтому я написал небольшой тестовый скрипт на своем Mac и не могу заставить его потерпеть неудачу - независимо от размера бассейна. Я изменил LinkedBlockingQueue
Чтобы быть неограниченным, иначе я не мог представить всю работу. Также через некоторое время isReachable()
Метод был бросал ConnectException
Поэтому мне пришлось справиться с этим конкретно. Это проблема с вашим кодом @user423199?
Вот код:
Мне интересно, на какую ОС вы запускаете это? Некоторые стеки IP могут не любить несколько потоков, выполняющих пакеты ICMP в одном и том же процессе. Я бы подумал, что все современные операционные системы будут разумными в этом, но это может быть потенциальной проблемой. Это также может быть какой -то ошибкой между Java JRE и стеком ОС.
Надеюсь это поможет.