2010-10-21 61 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