我有一个用 java 编写的应用程序,它需要找到网络上所有可访问的主机。
我用InetAddress.isReachable()
2000 毫秒的超时来执行此操作。
我查找当前本地机器的 IP 地址,并据此尝试访问以 1-255 结尾的其他 IP 地址,而丢失了本地机器的 IP 地址。
这一切都工作正常单线程,只是需要很长时间,因为大多数 IP 地址不存在,因为它们不存在,所以用完 2 秒超时。
为了加快速度(并在行动中尝试并发性 :: Brian Goetz),我尝试使用Future
等Callable
。
这一切也很顺利。
但是我想用ExecutorCompletionService
它来给我的用户一个响应速度更快的应用程序,这样他们就可以看到结果,因为他们可以使用
Future<Reach> reachedFuture = completionService.take();
在具有以下配置的单处理器机器上运行此程序会导致四个可访问主机中的一个被识别:
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()
调用会失败?