質問

Javaに書かれたアプリケーションがあり、ネットワーク上のすべての到達可能なホストを見つける必要があります。

私が使う InetAddress.isReachable() 2000ミリ秒のタイムアウトでこれを行うには。

現在のローカルマシンのIPアドレスを検索し、ローカルマシンIPアドレスを逃した1〜255を終了する他のIPアドレスに到達しようとします。

それはすべて正常に動作しますシングルスレッドで動作しますが、ほとんどのIPアドレスは存在しないために到達できないため、2秒のタイムアウトを使い果たすため、長い時間がかかります。

物事をスピードアップするために(そして、アクションの並行性を試してみてください:: Brian Goetz)私は使用しようとしました FutureCallable

これもすべてうまくいきました。

しかし、私は使用して空想しました ExecutorCompletionService ユーザーにより応答性の高いアプリケーションを提供するために、使用可能になったときに結果が表示される可能性があります

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

これを次の構成で単一プロセッサマシンで実行すると、4つの到達可能なホストのうち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秒になり、最後の構成作業はOKになりました。

また、Quad Coreマシンの次のように構成を変更することにより、2秒のタイムアウトでも動作しました。

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

なぜこれが起こるのか非常に明白なものが足りないのですか?

何が止まるか InetAddress.isReachable(2000) 私のネットワーク上のすべての到達可能なホストを検出することから?

なぜ複数を実行しようとするのか InetAddress.isReachable() 通話が失敗しますか?

役に立ちましたか?

解決

だから私は自分のMacに小さなテストスクリプトを書きましたが、プールのサイズに関係なく、失敗することはできません。私は変更しました LinkedBlockingQueue それ以外の場合は無制限になるために、私はすべてのジョブを提出することができませんでした。また、しばらくすると isReachable() 方法はスローしていました ConnectException だから私はそれを具体的に処理する必要がありました。これはあなたのコード @user423199の問題ですか?

これがコードです:

http://pastie.org/2460991

これを実行しているOSは何だと思いますか?特定のIPスタックは、同じプロセス内でICMPパケットを実行する複数のスレッドを好まない場合があります。私はすべての最新のオペレーティングシステムがそれについて賢いと思っていたでしょうが、これは潜在的な問題かもしれません。また、Java JREとOSスタックの間のバグかもしれません。

お役に立てれば。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top