[英]a funny thing happens… 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()
調用失敗?
所以我在我的Mac上寫了一個小測試腳本,我不能讓它失敗 - 無論池的大小。 我確實將LinkedBlockingQueue
更改為無限制,否則我無法提交所有作業。 此外,一段時間后, isReachable()
方法拋出一個ConnectException
所以我必須專門處理它。 這是您的代碼@ user423199的問題嗎?
這是代碼:
我想知道你在運行什么操作系統? 某些IP堆棧可能不喜歡在同一進程中執行ICMP數據包的多個線程。 我原以為所有現代操作系統都會很聰明,但這可能是一個潛在的問題。 它也可能是Java JRE和OS堆棧之間的一些錯誤。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.