简体   繁体   English

一件有趣的事情发生了...... ExecutorCompletionService

[英]a funny thing happens… ExecutorCompletionService

I have an application written in java that needs to find all the reachable hosts on the network. 我有一个用java编写的应用程序,需要找到网络上所有可访问的主机。

I use InetAddress.isReachable() to do this with a timeout of 2000 milliseconds. 我使用InetAddress.isReachable()来执行此操作,超时为2000毫秒。

I look up the current local machine's IP address and based on that I attempt to reach the other IP addresses that end 1 - 255 missing out the local machines IP address. 我查找当前本地计算机的IP地址,并在此基础上尝试访问结束1 - 255的其他IP地址,错过本地计算机的IP地址。

It all works fine single threaded, just takes a long time as most of the IP addresses are not reachable as they do not exist so use up the 2 second timeout. 这一切都工作得很好单线程,只需要很长时间,因为大多数IP地址不可访问,因为它们不存在,所以用完2秒超时。

To speed things up (and try out concurrency in action :: Brian Goetz) i tried using Future and Callable etc. 为了加快速度(并尝试运行中的并发性:: Brian Goetz)我尝试使用FutureCallable等。

This all went fine as well. 这一切都很顺利。

However i fancied using ExecutorCompletionService to give my users a more responsive application, so they could see results as they came available using 但是,我觉得使用ExecutorCompletionService为我的用户提供响应更快的应用程序,因此他们可以看到结果,因为它们可以使用

Future<Reach> reachedFuture = completionService.take();

Running this on a singleprocessor machine with the following config causes only 1 of the four reachable hosts to be identified: 使用以下配置在单处理器计算机上运行此配置会导致仅识别四个可访问主机中的一个:

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);

Changing it to this on a quad core machine also made it fail to detect all the reachable hosts: 在四核计算机上将其更改为此还使其无法检测到所有可访问的主机:

private static final int poolSize
        = Math.max(2,Runtime.getRuntime().availableProcessors());

private static final int maxPoolSize
        = Math.max(2,Runtime.getRuntime().availableProcessors());

By changing the InetAddress.isReachable() timeout to 10 seconds made the last config work ok. 通过将InetAddress.isReachable()超时更改为10秒,使最后一个配置正常工作。

Also by changing the config as follows on the quad core machine also made it work with a 2 second timeout: 此外,通过在四核计算机上更改配置如下也使其工作2秒超时:

private static final int poolSize = 2;
private static final int maxPoolSize = 2;

Am I missing something very obvious why this happens? 我错过了一些非常明显的原因吗?

What stops InetAddress.isReachable(2000) from detecting all the reachable hosts on my network? 什么阻止InetAddress.isReachable(2000)检测到我网络上所有可访问的主机?

Why does attempting to run multiple InetAddress.isReachable() calls fail? 为什么尝试运行多个InetAddress.isReachable()调用失败?

So I wrote a little test script on my Mac and I can't get it to fail -- regardless of the size of the pool. 所以我在我的Mac上写了一个小测试脚本,我不能让它失败 - 无论池的大小。 I did change the LinkedBlockingQueue to be unlimited otherwise I couldn't submit all of the jobs. 我确实将LinkedBlockingQueue更改为无限制,否则我无法提交所有作业。 Also, after a while the isReachable() method was throwing a ConnectException so I had to handle that specifically. 此外,一段时间后, isReachable()方法抛出一个ConnectException所以我必须专门处理它。 Is this the problem with your code @user423199? 这是您的代码@ user423199的问题吗?

Here's the code: 这是代码:

http://pastie.org/2460991 http://pastie.org/2460991

I'm wondering what OS you are running this on? 我想知道你在运行什么操作系统? Certain IP stacks may not like multiple threads doing ICMP packets within the same process. 某些IP堆栈可能不喜欢在同一进程中执行ICMP数据包的多个线程。 I would have thought that all modern operating systems would be smart about that but this may be a potential issue. 我原以为所有现代操作系统都会很聪明,但这可能是一个潜在的问题。 It also may be some bug between the Java JRE and the OS stack. 它也可能是Java JRE和OS堆栈之间的一些错误。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM