正确实现Java Future多线程

时间:2013-08-19 14:57:07

标签: java future

在我的servlet中,我正在点击几个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());

希望它对某人有用:)

1 个答案:

答案 0 :(得分: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));
}