3

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

InetAddress.isReachable()はこれを2000ミリ秒のタイムアウトで行うために使用します。

現在のローカルマシンのIPアドレスを検索し、それに基づいて、ローカルマシンのIPアドレスが欠落している1〜255で終わる他のIPアドレスに到達しようとします。

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

物事をスピードアップするために(そして実際に並行性を試すために:: Brian Goetz)私はFutureandCallableなどを使ってみました。

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

ただし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());

タイムアウトを10秒に変更することInetAddress.isReachable()で、最後の構成が正常に機能するようになりました。

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

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

なぜこれが起こるのか非常に明白な何かが欠けていますか?

InetAddress.isReachable(2000)ネットワーク上の到達可能なすべてのホストを検出できないのは何ですか?

InetAddress.isReachable()複数の呼び出しを実行しようとすると失敗するのはなぜですか?

4

1 に答える 1

1

そのため、Macで小さなテストスクリプトを作成しましたが、プールのサイズに関係なく、失敗させることはできません。LinkedBlockingQueueを無制限に変更しました。そうしないと、すべてのジョブを送信できませんでした。また、しばらくするとisReachable()メソッドがスローさConnectExceptionれていたので、具体的に処理する必要がありました。これはあなたのコード@user423199の問題ですか?

コードは次のとおりです。

http://pastie.org/2460991

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

お役に立てれば。

于 2011-08-31T17:23:51.940 に答える