3

私のサーブレットでは、いくつかの URL にアクセスしてステータスを確認し、ユーザーに応答を返しています。

複数のリクエストをヒットするには多くの時間がかかります: スレッドとタイムアウトが必要です。しかし、私は自分のスレッドが応答を得る必要があります:その理由でFutureを使用しています。

私のコードの概要:

ExecutorService executor = Executors.newFixedThreadPool(10);
Future<statusModel> future;

for (Map.Entry<String, String> url : urls.entrySet())
{
    try
    {
        future = executor.submit(new CallableRequestStatus(url.getValue()));
        status = (statusModel) future.get(5, TimeUnit.SECONDS);
        results.add(status);
    }
    catch (InterruptedException | ExecutionException | TimeoutException e) 
    {
        System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());  
    }
}
executor.shutdownNow();

呼び出し可能なクラスからのすべての結果は、後で arraylist に追加するステータス オブジェクトで取得されます。ここでの問題は、私のアプローチが 10 個のスレッドすべてを同時に実行することを妨げていることです。ステータス オブジェクトを取得するために 5 秒待機してから、次の URL に移動する必要があります。

私のアプローチは間違っていると思います。オンラインで調べてみましたが、カスタム オブジェクトと Arraylist が関係する例は見つかりませんでした。

誰かが私の過ちを正すのを手伝ってくれますか? 前もって感謝します

最後にコードを更新しました (Sotirios Delimanolis と Kevin に感謝):

ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<statusModel>> futures = new ArrayList<Future<statusModel>>();

for (Map.Entry<String, String> url : urls.entrySet())
{
    Future<statusModel> future = executor.submit(new CallableRequestStatus(url.getValue())); 
    futures.add(future);
}

ArrayList<statusModel> results = new ArrayList<statusModel>();
statusModel status;

int i=0;

for (Map.Entry<String, String> url : urls.entrySet())
{           
    try 
        {
            status = (statusModel) futures.get(i).get(500, TimeUnit.MILLISECONDS);
            // do some stuff with status and

            if(status.getStatusCode()/100 == 2)
                results.add(status);
        }
    catch (InterruptedException | ExecutionException | TimeoutException e) 
        {
            System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());  
        }   
i++;
}

executor.shutdownNow();
System.out.println("Shutdown: "+executor.isShutdown());

誰かに役立つことを願っています:)

4

1 に答える 1

2

すべてを事前に提出してから、個別に待つ必要があります。以下のように、わかりやすくするために例外処理を削除しました。

ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<statusModel>> futures = new ArrayList<>();

for (Map.Entry<String, String> url : urls.entrySet())
{
    futures.add(executor.submit(new CallableRequestStatus(url.getValue())));
}
for (Future<statusModel> f : futures) {
    results.add((statusModel) f.get(5, TimeUnit.SECONDS));
}
于 2013-08-19T15:16:10.630 に答える