一个有趣的事情发生了… ExecutorCompletionService
我有一个用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()
调用失败?
没有找到相关结果
已邀请:
1 个回复
俺呵誓放胳
改为无限制,否则我无法提交所有工作。此外,一段时间后
方法投掷了
所以我必须专门处理。这是您的代码@ user423199的问题吗? 这是代码: http://pastie.org/2460991 我想知道你在运行什么操作系统?某些IP堆栈可能不喜欢在同一进程中执行ICMP数据包的多个线程。我原以为所有现代操作系统都会很聪明,但这可能是一个潜在的问题。它也可能是Java JRE和OS堆栈之间的一些错误。 希望这可以帮助。