2010-10-21 62 views
3

我有一个用java编写的应用程序,需要找到网络上所有可访问的主机。一个有趣的事情发生...... ExecutorCompletionService

我使用InetAddress.isReachable()来做到这一点,超时时间为2000毫秒。

我查找当前本地计算机的IP地址,并基于此我试图到达其他IP地址,结束1-255丢失了本地计算机的IP地址。

这一切工作正常单线程,只需要很长的时间,因为大多数的IP地址不可访问,因为它们不存在,所以使用2秒超时。

为了加快速度(和尝试并发行动::作者Brian Goetz)我尝试使用FutureCallable

这一切都很好,以及。

但是我猜想使用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()调用失败?

+2

您是否尝试过使用'Executors.newSingleThreadExecutor()'来查看它是否是导致该问题的线程代码?这至少会引导我们走向正确的方向。 – 2011-04-29 13:09:40

回答

1

因此,我在我的Mac上写了一个小测试脚本,无法让它失败 - 无论池的大小如何。我确实将LinkedBlockingQueue更改为无限制,否则我无法提交所有作业。此外,经过一段时间isReachable()方法抛出ConnectException,所以我不得不专门处理。这是你的代码@ user423199的问题吗?

下面的代码:

http://pastie.org/2460991

我想知道你在运行这个什么操作系统?某些IP堆栈可能不喜欢在同一进程中执行ICMP数据包的多个线程。我本以为所有的现代操作系统都会很聪明,但这可能是一个潜在的问题。它也可能是Java JRE和OS栈之间的一些错误。

希望这会有所帮助。

+0

“某些IP堆栈可能不喜欢在同一进程内执行ICMP数据包的多个线程”:这不就是该平台的'InetAddress.isReachable()'实现中的一个错误吗? Java API不会将其限制为一个线程。 – Raedwald 2011-09-12 13:19:27

+0

可能或OS的IP堆栈中的限制。我真的在猜测。不知道是否会发生,但我想我会提到它。 – Gray 2011-09-12 14:56:03